From ced13eb7ca4ba73692151f9166ba42705a4793ad Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Thu, 28 Apr 2022 12:23:36 +0200 Subject: [PATCH 01/26] Add flake.nix (for the go server so far) --- flake.lock | 26 ++++++++++++++++++++++++++ flake.nix | 43 +++++++++++++++++++++++++++++++++++++++++++ serve/default.nix | 19 +++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 serve/default.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..ff6e3c6 --- /dev/null +++ b/flake.lock @@ -0,0 +1,26 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1642609835, + "narHash": "sha256-ZwJnV4mdis28u5vH240ec2mrApuEJYJekn23qlTwJ8c=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "77aa71f66fd05d9e7b7d1c084865d703a8008ab7", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-21.11", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..0880ea5 --- /dev/null +++ b/flake.nix @@ -0,0 +1,43 @@ +{ + description = "Triples card game"; + + # Nixpkgs / NixOS version to use. + inputs.nixpkgs.url = "nixpkgs/nixos-21.11"; + + outputs = { self, nixpkgs }: + let + + # to work with older version of flakes + lastModifiedDate = self.lastModifiedDate or self.lastModified or "19700101"; + + # Generate a user-friendly version number. + version = builtins.substring 0 8 lastModifiedDate; + + # System types to support. + supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; + + # Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'. + forAllSystems = nixpkgs.lib.genAttrs supportedSystems; + + # Nixpkgs instantiated for supported system types. + nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); + + in + { + # Provide some binary packages for selected system types. + packages = forAllSystems (system: + let + pkgs = nixpkgsFor.${system}; + in + { + triples-serve = pkgs.callPackage ./serve/default.nix { + inherit version; + }; + }); + + # The default package for 'nix build'. This makes sense if the + # flake provides only one package or there is a clear "main" + # package. + defaultPackage = forAllSystems (system: self.packages.${system}.triples-serve); + }; +} diff --git a/serve/default.nix b/serve/default.nix new file mode 100644 index 0000000..d3320ec --- /dev/null +++ b/serve/default.nix @@ -0,0 +1,19 @@ +{ pkgs, version }: +pkgs.buildGoModule { + pname = "triples-serve"; + inherit version; + + # In 'nix develop', we don't need a copy of the source tree + # in the Nix store. + src = ./.; + + # This hash locks the dependencies of this package. It is + # necessary because of how Go requires network access to resolve + # VCS. See https://www.tweag.io/blog/2021-03-04-gomod2nix/ for + # details. Normally one can build with a fake sha256 and rely on native Go + # mechanisms to tell you what the hash should be or determine what + # it should be "out-of-band" with other tooling (eg. gomod2nix). + # To begin with it is recommended to set this, but one must + # remember to bump this hash when your dependencies change. + vendorSha256 = "sha256-gP92Prsu1ZFUmYEcf99LuPMxFoJ24Wi+m2u6W+FrIX8="; +} From 88f1d5ed3d11dac69765fefb91e6697cc947b24e Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Thu, 28 Apr 2022 12:25:41 +0200 Subject: [PATCH 02/26] break a test --- serve/blob_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serve/blob_test.go b/serve/blob_test.go index 7fd4a8f..52de455 100644 --- a/serve/blob_test.go +++ b/serve/blob_test.go @@ -21,7 +21,7 @@ func TestBlob(t *testing.T) { func TestBlobShort(t *testing.T) { k := genKey() _, err := decode("short", k) - if err == nil { + if err != nil { t.Error("expected error") } } From 04965feba1509f048f200fa7395a4a943de9c934 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Thu, 28 Apr 2022 12:27:02 +0200 Subject: [PATCH 03/26] Revert "break a test" This reverts commit 88f1d5ed3d11dac69765fefb91e6697cc947b24e. --- serve/blob_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serve/blob_test.go b/serve/blob_test.go index 52de455..7fd4a8f 100644 --- a/serve/blob_test.go +++ b/serve/blob_test.go @@ -21,7 +21,7 @@ func TestBlob(t *testing.T) { func TestBlobShort(t *testing.T) { k := genKey() _, err := decode("short", k) - if err != nil { + if err == nil { t.Error("expected error") } } From 91f42ee975396456354f68c5cdd5bc671485cea0 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Thu, 28 Apr 2022 13:55:34 +0200 Subject: [PATCH 04/26] Remove default flake package --- flake.nix | 5 ----- 1 file changed, 5 deletions(-) diff --git a/flake.nix b/flake.nix index 0880ea5..39a11ef 100644 --- a/flake.nix +++ b/flake.nix @@ -34,10 +34,5 @@ inherit version; }; }); - - # The default package for 'nix build'. This makes sense if the - # flake provides only one package or there is a clear "main" - # package. - defaultPackage = forAllSystems (system: self.packages.${system}.triples-serve); }; } From 8fab26c4860f97c74ca297cba5e171f39428dd14 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Thu, 28 Apr 2022 13:58:18 +0200 Subject: [PATCH 05/26] cut nix comments --- serve/default.nix | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/serve/default.nix b/serve/default.nix index d3320ec..236607a 100644 --- a/serve/default.nix +++ b/serve/default.nix @@ -2,18 +2,6 @@ pkgs.buildGoModule { pname = "triples-serve"; inherit version; - - # In 'nix develop', we don't need a copy of the source tree - # in the Nix store. src = ./.; - - # This hash locks the dependencies of this package. It is - # necessary because of how Go requires network access to resolve - # VCS. See https://www.tweag.io/blog/2021-03-04-gomod2nix/ for - # details. Normally one can build with a fake sha256 and rely on native Go - # mechanisms to tell you what the hash should be or determine what - # it should be "out-of-band" with other tooling (eg. gomod2nix). - # To begin with it is recommended to set this, but one must - # remember to bump this hash when your dependencies change. vendorSha256 = "sha256-gP92Prsu1ZFUmYEcf99LuPMxFoJ24Wi+m2u6W+FrIX8="; } From a9893f5cdc27f7bbcb318cf1cb27aa41e86037ef Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Fri, 29 Apr 2022 13:16:41 +0200 Subject: [PATCH 06/26] vendor elm dependencies It should now be possible to run elm-make without it needing to download anything. Done by: - running elm-make with internet connection, and adding elm-stuff/exact-dependencies.json and elm-stuff/packages - some manual tweaks for the unreleased elm-edn 1.4.0 --- .gitignore | 2 +- client/default.nix | 22 + client/elm-package.json | 6 +- client/elm-stuff/exact-dependencies.json | 15 + .../elm-community/list-extra/7.1.0/.gitignore | 2 + .../list-extra/7.1.0/.travis.yml | 36 + .../elm-community/list-extra/7.1.0/LICENSE | 21 + .../elm-community/list-extra/7.1.0/README.md | 24 + .../list-extra/7.1.0/elm-package.json | 16 + .../list-extra/7.1.0/src/List/Extra.elm | 1683 +++++++++++++++ .../list-extra/7.1.0/tests/.gitignore | 1 + .../list-extra/7.1.0/tests/Tests.elm | 676 ++++++ .../list-extra/7.1.0/tests/elm-package.json | 19 + .../random-extra/2.0.0/.gitignore | 1 + .../random-extra/2.0.0/README.md | 13 + .../random-extra/2.0.0/elm-package.json | 27 + .../random-extra/2.0.0/src/Random/Array.elm | 104 + .../random-extra/2.0.0/src/Random/Char.elm | 1390 ++++++++++++ .../random-extra/2.0.0/src/Random/Color.elm | 77 + .../random-extra/2.0.0/src/Random/Date.elm | 99 + .../random-extra/2.0.0/src/Random/Dict.elm | 28 + .../random-extra/2.0.0/src/Random/Extra.elm | 354 ++++ .../random-extra/2.0.0/src/Random/Float.elm | 67 + .../random-extra/2.0.0/src/Random/Int.elm | 45 + .../random-extra/2.0.0/src/Random/List.elm | 75 + .../random-extra/2.0.0/src/Random/Order.elm | 21 + .../random-extra/2.0.0/src/Random/Set.elm | 62 + .../random-extra/2.0.0/src/Random/String.elm | 28 + .../packages/elm-lang/core/5.1.1/.eslintrc | 156 ++ .../packages/elm-lang/core/5.1.1/.gitignore | 3 + .../packages/elm-lang/core/5.1.1/.travis.yml | 35 + .../elm-lang/core/5.1.1/CONTRIBUTING.md | 43 + .../packages/elm-lang/core/5.1.1/LICENSE | 30 + .../packages/elm-lang/core/5.1.1/README.md | 34 + .../packages/elm-lang/core/5.1.1/changelog.md | 143 ++ .../elm-lang/core/5.1.1/elm-package.json | 38 + .../elm-lang/core/5.1.1/src/Array.elm | 240 +++ .../elm-lang/core/5.1.1/src/Basics.elm | 650 ++++++ .../elm-lang/core/5.1.1/src/Bitwise.elm | 90 + .../packages/elm-lang/core/5.1.1/src/Char.elm | 103 + .../elm-lang/core/5.1.1/src/Color.elm | 456 ++++ .../packages/elm-lang/core/5.1.1/src/Date.elm | 150 ++ .../elm-lang/core/5.1.1/src/Debug.elm | 62 + .../packages/elm-lang/core/5.1.1/src/Dict.elm | 661 ++++++ .../elm-lang/core/5.1.1/src/Json/Decode.elm | 520 +++++ .../elm-lang/core/5.1.1/src/Json/Encode.elm | 102 + .../packages/elm-lang/core/5.1.1/src/List.elm | 613 ++++++ .../elm-lang/core/5.1.1/src/Maybe.elm | 157 ++ .../elm-lang/core/5.1.1/src/Native/Array.js | 967 +++++++++ .../elm-lang/core/5.1.1/src/Native/Basics.js | 141 ++ .../elm-lang/core/5.1.1/src/Native/Bitwise.js | 13 + .../elm-lang/core/5.1.1/src/Native/Char.js | 14 + .../elm-lang/core/5.1.1/src/Native/Date.js | 33 + .../elm-lang/core/5.1.1/src/Native/Debug.js | 30 + .../elm-lang/core/5.1.1/src/Native/Json.js | 575 +++++ .../elm-lang/core/5.1.1/src/Native/List.js | 137 ++ .../core/5.1.1/src/Native/Platform.js | 559 +++++ .../elm-lang/core/5.1.1/src/Native/Regex.js | 119 ++ .../core/5.1.1/src/Native/Scheduler.js | 281 +++ .../elm-lang/core/5.1.1/src/Native/String.js | 339 +++ .../elm-lang/core/5.1.1/src/Native/Time.js | 27 + .../elm-lang/core/5.1.1/src/Native/Utils.js | 488 +++++ .../elm-lang/core/5.1.1/src/Platform.elm | 145 ++ .../elm-lang/core/5.1.1/src/Platform/Cmd.elm | 67 + .../elm-lang/core/5.1.1/src/Platform/Sub.elm | 52 + .../elm-lang/core/5.1.1/src/Process.elm | 106 + .../elm-lang/core/5.1.1/src/Random.elm | 532 +++++ .../elm-lang/core/5.1.1/src/Regex.elm | 148 ++ .../elm-lang/core/5.1.1/src/Result.elm | 210 ++ .../packages/elm-lang/core/5.1.1/src/Set.elm | 168 ++ .../elm-lang/core/5.1.1/src/String.elm | 464 ++++ .../packages/elm-lang/core/5.1.1/src/Task.elm | 277 +++ .../packages/elm-lang/core/5.1.1/src/Time.elm | 243 +++ .../elm-lang/core/5.1.1/src/Tuple.elm | 61 + .../elm-lang/core/5.1.1/tests/Main.elm | 50 + .../elm-lang/core/5.1.1/tests/Test/Array.elm | 120 ++ .../elm-lang/core/5.1.1/tests/Test/Basics.elm | 220 ++ .../core/5.1.1/tests/Test/Bitwise.elm | 51 + .../elm-lang/core/5.1.1/tests/Test/Char.elm | 113 + .../core/5.1.1/tests/Test/CodeGen.elm | 109 + .../elm-lang/core/5.1.1/tests/Test/Dict.elm | 107 + .../core/5.1.1/tests/Test/Equality.elm | 34 + .../elm-lang/core/5.1.1/tests/Test/Json.elm | 84 + .../elm-lang/core/5.1.1/tests/Test/List.elm | 160 ++ .../elm-lang/core/5.1.1/tests/Test/Maybe.elm | 169 ++ .../elm-lang/core/5.1.1/tests/Test/Regex.elm | 57 + .../elm-lang/core/5.1.1/tests/Test/Result.elm | 70 + .../elm-lang/core/5.1.1/tests/Test/Set.elm | 52 + .../elm-lang/core/5.1.1/tests/Test/String.elm | 110 + .../core/5.1.1/tests/elm-package.json | 17 + .../elm-lang/core/5.1.1/tests/run-tests.sh | 19 + .../packages/elm-lang/dom/1.1.1/.gitignore | 1 + .../packages/elm-lang/dom/1.1.1/LICENSE | 30 + .../packages/elm-lang/dom/1.1.1/README.md | 7 + .../dom/1.1.1/assets/boundaries.acorn | Bin 0 -> 188416 bytes .../elm-lang/dom/1.1.1/assets/boundaries.png | Bin 0 -> 54799 bytes .../elm-lang/dom/1.1.1/elm-package.json | 19 + .../packages/elm-lang/dom/1.1.1/src/Dom.elm | 69 + .../elm-lang/dom/1.1.1/src/Dom/LowLevel.elm | 37 + .../elm-lang/dom/1.1.1/src/Dom/Scroll.elm | 119 ++ .../elm-lang/dom/1.1.1/src/Dom/Size.elm | 59 + .../elm-lang/dom/1.1.1/src/Native/Dom.js | 182 ++ .../packages/elm-lang/html/2.0.0/.gitignore | 1 + .../packages/elm-lang/html/2.0.0/LICENSE | 30 + .../packages/elm-lang/html/2.0.0/README.md | 5 + .../elm-lang/html/2.0.0/elm-package.json | 21 + .../html/2.0.0/properties-vs-attributes.md | 15 + .../packages/elm-lang/html/2.0.0/src/Html.elm | 923 ++++++++ .../html/2.0.0/src/Html/Attributes.elm | 1009 +++++++++ .../elm-lang/html/2.0.0/src/Html/Events.elm | 269 +++ .../elm-lang/html/2.0.0/src/Html/Keyed.elm | 48 + .../elm-lang/html/2.0.0/src/Html/Lazy.elm | 48 + .../packages/elm-lang/http/1.0.0/.gitignore | 1 + .../packages/elm-lang/http/1.0.0/LICENSE | 30 + .../packages/elm-lang/http/1.0.0/README.md | 57 + .../elm-lang/http/1.0.0/elm-package.json | 18 + .../elm-lang/http/1.0.0/rate-limit.md | 40 + .../packages/elm-lang/http/1.0.0/src/Http.elm | 411 ++++ .../elm-lang/http/1.0.0/src/Http/Internal.elm | 45 + .../elm-lang/http/1.0.0/src/Http/Progress.elm | 200 ++ .../elm-lang/http/1.0.0/src/Native/Http.js | 238 +++ .../elm-lang/navigation/2.1.0/.gitignore | 1 + .../elm-lang/navigation/2.1.0/LICENSE | 30 + .../elm-lang/navigation/2.1.0/README.md | 28 + .../navigation/2.1.0/elm-package.json | 19 + .../navigation/2.1.0/examples/Example.elm | 78 + .../navigation/2.1.0/examples/README.md | 12 + .../2.1.0/examples/elm-package.json | 18 + .../navigation/2.1.0/src/Native/Navigation.js | 107 + .../navigation/2.1.0/src/Navigation.elm | 424 ++++ .../packages/elm-lang/svg/2.0.0/.gitignore | 1 + .../packages/elm-lang/svg/2.0.0/LICENSE | 30 + .../packages/elm-lang/svg/2.0.0/README.md | 9 + .../elm-lang/svg/2.0.0/elm-package.json | 22 + .../elm-lang/svg/2.0.0/examples/Logo.elm | 19 + .../packages/elm-lang/svg/2.0.0/src/Svg.elm | 611 ++++++ .../elm-lang/svg/2.0.0/src/Svg/Attributes.elm | 1618 ++++++++++++++ .../elm-lang/svg/2.0.0/src/Svg/Events.elm | 178 ++ .../elm-lang/svg/2.0.0/src/Svg/Keyed.elm | 37 + .../elm-lang/svg/2.0.0/src/Svg/Lazy.elm | 48 + .../elm-lang/virtual-dom/2.0.4/.gitignore | 3 + .../elm-lang/virtual-dom/2.0.4/.travis.yml | 8 + .../elm-lang/virtual-dom/2.0.4/LICENSE | 30 + .../elm-lang/virtual-dom/2.0.4/README.md | 5 + .../virtual-dom/2.0.4/elm-package.json | 17 + .../virtual-dom/2.0.4/src/Native/Debug.js | 280 +++ .../2.0.4/src/Native/VirtualDom.js | 1881 +++++++++++++++++ .../virtual-dom/2.0.4/src/VirtualDom.elm | 331 +++ .../2.0.4/src/VirtualDom/Debug.elm | 567 +++++ .../2.0.4/src/VirtualDom/Expando.elm | 659 ++++++ .../2.0.4/src/VirtualDom/Helpers.elm | 137 ++ .../2.0.4/src/VirtualDom/History.elm | 290 +++ .../2.0.4/src/VirtualDom/Metadata.elm | 326 +++ .../2.0.4/src/VirtualDom/Overlay.elm | 541 +++++ .../2.0.4/src/VirtualDom/Report.elm | 99 + .../2.0.4/tests/Native/TestHelpers.js | 35 + .../2.0.4/tests/TestCases/Lazy.elm | 72 + .../virtual-dom/2.0.4/tests/TestHelpers.elm | 34 + .../virtual-dom/2.0.4/tests/TestMain.elm | 18 + .../virtual-dom/2.0.4/tests/elm-package.json | 18 + .../virtual-dom/2.0.4/tests/run-tests.sh | 24 + .../elm-lang/websocket/1.0.2/.gitignore | 1 + .../packages/elm-lang/websocket/1.0.2/LICENSE | 30 + .../elm-lang/websocket/1.0.2/README.md | 22 + .../elm-lang/websocket/1.0.2/elm-package.json | 18 + .../websocket/1.0.2/src/Native/WebSocket.js | 99 + .../websocket/1.0.2/src/WebSocket.elm | 347 +++ .../1.0.2/src/WebSocket/LowLevel.elm | 147 ++ .../parser-primitives/1.0.0/.gitignore | 1 + .../elm-tools/parser-primitives/1.0.0/LICENSE | 27 + .../parser-primitives/1.0.0/README.md | 7 + .../parser-primitives/1.0.0/elm-package.json | 17 + .../1.0.0/src/Native/ParserPrimitives.js | 130 ++ .../1.0.0/src/ParserPrimitives.elm | 109 + .../evancz/url-parser/2.0.1/.gitignore | 1 + .../packages/evancz/url-parser/2.0.1/LICENSE | 27 + .../evancz/url-parser/2.0.1/README.md | 67 + .../evancz/url-parser/2.0.1/elm-package.json | 18 + .../url-parser/2.0.1/examples/Example.elm | 128 ++ .../url-parser/2.0.1/examples/README.md | 12 + .../2.0.1/examples/elm-package.json | 18 + .../evancz/url-parser/2.0.1/src/UrlParser.elm | 414 ++++ .../robx/elm-edn/1.4.0/elm-package.json | 20 + .../robx/elm-edn/1.4.0/src/Decode.elm | 841 ++++++++ .../robx/elm-edn/1.4.0/src/Encode.elm | 381 ++++ .../packages/robx/elm-edn/1.4.0/src/Parse.elm | 555 +++++ .../robx/elm-edn/1.4.0/src/Parser.elm | 1050 +++++++++ .../packages/robx/elm-edn/1.4.0/src/Types.elm | 29 + 188 files changed, 34047 insertions(+), 4 deletions(-) create mode 100644 client/default.nix create mode 100644 client/elm-stuff/exact-dependencies.json create mode 100644 client/elm-stuff/packages/elm-community/list-extra/7.1.0/.gitignore create mode 100644 client/elm-stuff/packages/elm-community/list-extra/7.1.0/.travis.yml create mode 100644 client/elm-stuff/packages/elm-community/list-extra/7.1.0/LICENSE create mode 100644 client/elm-stuff/packages/elm-community/list-extra/7.1.0/README.md create mode 100644 client/elm-stuff/packages/elm-community/list-extra/7.1.0/elm-package.json create mode 100644 client/elm-stuff/packages/elm-community/list-extra/7.1.0/src/List/Extra.elm create mode 100644 client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/.gitignore create mode 100644 client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/Tests.elm create mode 100644 client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/elm-package.json create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/.gitignore create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/README.md create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/elm-package.json create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Array.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Char.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Color.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Date.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Dict.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Extra.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Float.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Int.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/List.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Order.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Set.elm create mode 100644 client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/String.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/.eslintrc create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/.gitignore create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/.travis.yml create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/CONTRIBUTING.md create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/LICENSE create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/README.md create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/changelog.md create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/elm-package.json create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Array.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Basics.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Bitwise.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Char.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Color.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Date.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Debug.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Dict.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Json/Decode.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Json/Encode.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/List.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Maybe.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Array.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Basics.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Bitwise.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Char.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Date.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Debug.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Json.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/List.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Platform.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Regex.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Scheduler.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/String.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Time.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Utils.js create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform/Cmd.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform/Sub.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Process.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Random.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Regex.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Result.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Set.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/String.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Task.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Time.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/src/Tuple.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Main.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Array.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Basics.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Bitwise.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Char.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/CodeGen.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Dict.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Equality.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Json.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/List.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Maybe.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Regex.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Result.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Set.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/String.elm create mode 100644 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/elm-package.json create mode 100755 client/elm-stuff/packages/elm-lang/core/5.1.1/tests/run-tests.sh create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/.gitignore create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/LICENSE create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/README.md create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/assets/boundaries.acorn create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/assets/boundaries.png create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/elm-package.json create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/src/Dom.elm create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/src/Dom/LowLevel.elm create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/src/Dom/Scroll.elm create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/src/Dom/Size.elm create mode 100644 client/elm-stuff/packages/elm-lang/dom/1.1.1/src/Native/Dom.js create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/.gitignore create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/LICENSE create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/README.md create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/elm-package.json create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/properties-vs-attributes.md create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/src/Html.elm create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/src/Html/Attributes.elm create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/src/Html/Events.elm create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/src/Html/Keyed.elm create mode 100644 client/elm-stuff/packages/elm-lang/html/2.0.0/src/Html/Lazy.elm create mode 100644 client/elm-stuff/packages/elm-lang/http/1.0.0/.gitignore create mode 100644 client/elm-stuff/packages/elm-lang/http/1.0.0/LICENSE create mode 100644 client/elm-stuff/packages/elm-lang/http/1.0.0/README.md create mode 100644 client/elm-stuff/packages/elm-lang/http/1.0.0/elm-package.json create mode 100644 client/elm-stuff/packages/elm-lang/http/1.0.0/rate-limit.md create mode 100644 client/elm-stuff/packages/elm-lang/http/1.0.0/src/Http.elm create mode 100644 client/elm-stuff/packages/elm-lang/http/1.0.0/src/Http/Internal.elm create mode 100644 client/elm-stuff/packages/elm-lang/http/1.0.0/src/Http/Progress.elm create mode 100644 client/elm-stuff/packages/elm-lang/http/1.0.0/src/Native/Http.js create mode 100644 client/elm-stuff/packages/elm-lang/navigation/2.1.0/.gitignore create mode 100644 client/elm-stuff/packages/elm-lang/navigation/2.1.0/LICENSE create mode 100644 client/elm-stuff/packages/elm-lang/navigation/2.1.0/README.md create mode 100644 client/elm-stuff/packages/elm-lang/navigation/2.1.0/elm-package.json create mode 100644 client/elm-stuff/packages/elm-lang/navigation/2.1.0/examples/Example.elm create mode 100644 client/elm-stuff/packages/elm-lang/navigation/2.1.0/examples/README.md create mode 100644 client/elm-stuff/packages/elm-lang/navigation/2.1.0/examples/elm-package.json create mode 100644 client/elm-stuff/packages/elm-lang/navigation/2.1.0/src/Native/Navigation.js create mode 100644 client/elm-stuff/packages/elm-lang/navigation/2.1.0/src/Navigation.elm create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/.gitignore create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/LICENSE create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/README.md create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/elm-package.json create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/examples/Logo.elm create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/src/Svg.elm create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/src/Svg/Attributes.elm create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/src/Svg/Events.elm create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/src/Svg/Keyed.elm create mode 100644 client/elm-stuff/packages/elm-lang/svg/2.0.0/src/Svg/Lazy.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/.gitignore create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/.travis.yml create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/LICENSE create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/README.md create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/elm-package.json create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/Native/Debug.js create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/Native/VirtualDom.js create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/VirtualDom.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/VirtualDom/Debug.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/VirtualDom/Expando.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/VirtualDom/Helpers.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/VirtualDom/History.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/VirtualDom/Metadata.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/VirtualDom/Overlay.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/src/VirtualDom/Report.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/tests/Native/TestHelpers.js create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/tests/TestCases/Lazy.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/tests/TestHelpers.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/tests/TestMain.elm create mode 100644 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/tests/elm-package.json create mode 100755 client/elm-stuff/packages/elm-lang/virtual-dom/2.0.4/tests/run-tests.sh create mode 100644 client/elm-stuff/packages/elm-lang/websocket/1.0.2/.gitignore create mode 100644 client/elm-stuff/packages/elm-lang/websocket/1.0.2/LICENSE create mode 100644 client/elm-stuff/packages/elm-lang/websocket/1.0.2/README.md create mode 100644 client/elm-stuff/packages/elm-lang/websocket/1.0.2/elm-package.json create mode 100644 client/elm-stuff/packages/elm-lang/websocket/1.0.2/src/Native/WebSocket.js create mode 100644 client/elm-stuff/packages/elm-lang/websocket/1.0.2/src/WebSocket.elm create mode 100644 client/elm-stuff/packages/elm-lang/websocket/1.0.2/src/WebSocket/LowLevel.elm create mode 100644 client/elm-stuff/packages/elm-tools/parser-primitives/1.0.0/.gitignore create mode 100644 client/elm-stuff/packages/elm-tools/parser-primitives/1.0.0/LICENSE create mode 100644 client/elm-stuff/packages/elm-tools/parser-primitives/1.0.0/README.md create mode 100644 client/elm-stuff/packages/elm-tools/parser-primitives/1.0.0/elm-package.json create mode 100644 client/elm-stuff/packages/elm-tools/parser-primitives/1.0.0/src/Native/ParserPrimitives.js create mode 100644 client/elm-stuff/packages/elm-tools/parser-primitives/1.0.0/src/ParserPrimitives.elm create mode 100644 client/elm-stuff/packages/evancz/url-parser/2.0.1/.gitignore create mode 100644 client/elm-stuff/packages/evancz/url-parser/2.0.1/LICENSE create mode 100644 client/elm-stuff/packages/evancz/url-parser/2.0.1/README.md create mode 100644 client/elm-stuff/packages/evancz/url-parser/2.0.1/elm-package.json create mode 100644 client/elm-stuff/packages/evancz/url-parser/2.0.1/examples/Example.elm create mode 100644 client/elm-stuff/packages/evancz/url-parser/2.0.1/examples/README.md create mode 100644 client/elm-stuff/packages/evancz/url-parser/2.0.1/examples/elm-package.json create mode 100644 client/elm-stuff/packages/evancz/url-parser/2.0.1/src/UrlParser.elm create mode 100644 client/elm-stuff/packages/robx/elm-edn/1.4.0/elm-package.json create mode 100644 client/elm-stuff/packages/robx/elm-edn/1.4.0/src/Decode.elm create mode 100644 client/elm-stuff/packages/robx/elm-edn/1.4.0/src/Encode.elm create mode 100644 client/elm-stuff/packages/robx/elm-edn/1.4.0/src/Parse.elm create mode 100644 client/elm-stuff/packages/robx/elm-edn/1.4.0/src/Parser.elm create mode 100644 client/elm-stuff/packages/robx/elm-edn/1.4.0/src/Types.elm diff --git a/.gitignore b/.gitignore index 0b68274..829fad3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -elm-stuff +elm-stuff/build-artifacts static/main.js serve/serve diff --git a/client/default.nix b/client/default.nix new file mode 100644 index 0000000..cb2dd3b --- /dev/null +++ b/client/default.nix @@ -0,0 +1,22 @@ +{ pkgs ? import {}, + foo ? "hello", + old ? import (builtins.fetchTarball "https://nixos.org/channels/nixos-18.03/nixexprs.tar.xz") {} +}: + +pkgs.stdenv.mkDerivation rec { + name = "triples-client-${version}"; + version = "xxx"; + + src = ./.; + + buildInputs = [ old.elmPackages.elm ]; + + buildPhase = '' + elm-make src/Main.elm --yes --output main.js + ''; + + installPhase = '' + mkdir -p $out + cp main.js $out/main.js + ''; +} diff --git a/client/elm-package.json b/client/elm-package.json index 0209c7b..5b3db6d 100644 --- a/client/elm-package.json +++ b/client/elm-package.json @@ -4,8 +4,7 @@ "repository": "https://github.com/robx/noexist.git", "license": "BSD3", "source-directories": [ - "src", - "/s/elm-edn/src" + "src" ], "exposed-modules": [], "dependencies": { @@ -18,7 +17,8 @@ "elm-lang/navigation": "2.1.0 <= v < 3.0.0", "evancz/url-parser": "2.0.0 <= v < 3.0.0", "elm-lang/websocket": "1.0.2 <= v < 2.0.0", - "elm-tools/parser-primitives": "1.0.0 <= v < 2.0.0" + "elm-tools/parser-primitives": "1.0.0 <= v < 2.0.0", + "robx/elm-edn": "1.4.0 <= v < 2.0.0" }, "elm-version": "0.18.0 <= v < 0.19.0" } diff --git a/client/elm-stuff/exact-dependencies.json b/client/elm-stuff/exact-dependencies.json new file mode 100644 index 0000000..9b2119c --- /dev/null +++ b/client/elm-stuff/exact-dependencies.json @@ -0,0 +1,15 @@ +{ + "elm-tools/parser-primitives": "1.0.0", + "elm-lang/navigation": "2.1.0", + "elm-lang/virtual-dom": "2.0.4", + "evancz/url-parser": "2.0.1", + "elm-community/random-extra": "2.0.0", + "elm-lang/dom": "1.1.1", + "elm-lang/websocket": "1.0.2", + "elm-lang/html": "2.0.0", + "elm-lang/http": "1.0.0", + "elm-community/list-extra": "7.1.0", + "elm-lang/svg": "2.0.0", + "elm-lang/core": "5.1.1", + "robx/elm-edn": "1.4.0" +} diff --git a/client/elm-stuff/packages/elm-community/list-extra/7.1.0/.gitignore b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/.gitignore new file mode 100644 index 0000000..5f11fd6 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/.gitignore @@ -0,0 +1,2 @@ +# Ignore build or dist files +/elm-stuff diff --git a/client/elm-stuff/packages/elm-community/list-extra/7.1.0/.travis.yml b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/.travis.yml new file mode 100644 index 0000000..1b37aa9 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/.travis.yml @@ -0,0 +1,36 @@ +sudo: false + +language: node_js +node_js: node + +cache: + directories: + - elm-stuff/build-artifacts + - elm-stuff/packages + - sysconfcpus + +os: + - linux + +before_install: + - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + +install: + - npm install -g elm elm-test + - elm package install --yes + - | + if [ ! -d "$TRAVIS_BUILD_DIR/sysconfcpus/bin" ]; + then + git clone https://github.com/obmarg/libsysconfcpus.git; + cd libsysconfcpus; + ./configure --prefix=$TRAVIS_BUILD_DIR/sysconfcpus; + make && make install; + cd ..; + fi + +before_script: + - $TRAVIS_BUILD_DIR/sysconfcpus/bin/sysconfcpus -n 2 elm-make --yes src/List/Extra.elm + - cd tests && $TRAVIS_BUILD_DIR/sysconfcpus/bin/sysconfcpus -n 2 elm-make --yes Tests.elm ../src/List/Extra.elm && cd .. + +script: + - $TRAVIS_BUILD_DIR/sysconfcpus/bin/sysconfcpus -n 2 elm-test diff --git a/client/elm-stuff/packages/elm-community/list-extra/7.1.0/LICENSE b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/LICENSE new file mode 100644 index 0000000..a5303f3 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 CircuitHub Inc., Elm Community members + +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/client/elm-stuff/packages/elm-community/list-extra/7.1.0/README.md b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/README.md new file mode 100644 index 0000000..1302449 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/README.md @@ -0,0 +1,24 @@ +# Convenience functions for working with List + +[![Build Status](https://travis-ci.org/elm-community/list-extra.svg?branch=master)](https://travis-ci.org/elm-community/list-extra) + +Experimental package with convenience functions for working with List. +Note that this API is experimental and likely to go through many more iterations. + +Feedback and contributions are very welcome. + +## Run tests + +This package uses [elm-test](https://github.com/elm-community/elm-test), please read its documentation to know how to run tests. + +## Contributing + +Pull requests are welcome. You can expect some kind of response within 5 days. + +If you are adding a new function please.. + +0. Include [documentation](http://package.elm-lang.org/help/documentation-format) and make sure it has a code snippet demonstrating what the function does. +1. Give a detailed use case where your function would come in handy in the PR. +2. Add tests to `Tests/Tests.elm` + +If you are improving existing functions please demonstrate the performance gains in something like [Ellie](https://ellie-app.com/) and by using a benchmark library like [this one](http://package.elm-lang.org/packages/BrianHicks/elm-benchmark/latest). diff --git a/client/elm-stuff/packages/elm-community/list-extra/7.1.0/elm-package.json b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/elm-package.json new file mode 100644 index 0000000..1bde809 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/elm-package.json @@ -0,0 +1,16 @@ +{ + "version": "7.1.0", + "summary": "Convenience functions for working with List", + "repository": "https://github.com/elm-community/list-extra.git", + "license": "MIT", + "source-directories": [ + "src" + ], + "exposed-modules": [ + "List.Extra" + ], + "dependencies": { + "elm-lang/core": "5.1.1 <= v < 6.0.0" + }, + "elm-version": "0.18.0 <= v < 0.19.0" +} diff --git a/client/elm-stuff/packages/elm-community/list-extra/7.1.0/src/List/Extra.elm b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/src/List/Extra.elm new file mode 100644 index 0000000..5ee3103 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/src/List/Extra.elm @@ -0,0 +1,1683 @@ +module List.Extra + exposing + ( last + , init + , getAt + , (!!) + , uncons + , minimumBy + , maximumBy + , andMap + , andThen + , reverseMap + , takeWhile + , dropWhile + , unique + , uniqueBy + , allDifferent + , allDifferentBy + , replaceIf + , setAt + , swapAt + , stableSortWith + , remove + , updateIf + , updateAt + , updateIfIndex + , removeAt + , removeIfIndex + , filterNot + , iterate + , initialize + , cycle + , intercalate + , transpose + , subsequences + , permutations + , interweave + , cartesianProduct + , foldl1 + , foldr1 + , indexedFoldl + , indexedFoldr + , scanl1 + , scanr + , scanr1 + , mapAccuml + , mapAccumr + , unfoldr + , splitAt + , splitWhen + , takeWhileRight + , dropWhileRight + , span + , break + , stripPrefix + , group + , groupWhile + , groupWhileTransitively + , inits + , tails + , select + , selectSplit + , isPrefixOf + , isSuffixOf + , isInfixOf + , isSubsequenceOf + , isPermutationOf + , notMember + , find + , elemIndex + , elemIndices + , findIndex + , findIndices + , count + , zip + , zip3 + , zip4 + , zip5 + , lift2 + , lift3 + , lift4 + , groupsOf + , groupsOfWithStep + , greedyGroupsOf + , greedyGroupsOfWithStep + , groupsOfVarying + ) + +{-| Convenience functions for working with List + + +# Basics + +@docs last, init, getAt, (!!), uncons, maximumBy, minimumBy, andMap, andThen, reverseMap, takeWhile, dropWhile, unique, uniqueBy, allDifferent, allDifferentBy, replaceIf, setAt, remove, updateIf, updateAt, updateIfIndex, removeAt, removeIfIndex, filterNot, swapAt, stableSortWith + + +# List transformations + +@docs intercalate, transpose, subsequences, permutations, interweave, cartesianProduct + + +# Folds + +@docs foldl1, foldr1, indexedFoldl, indexedFoldr + + +# Building lists + +@docs scanl1, scanr, scanr1, mapAccuml, mapAccumr, unfoldr, iterate, initialize, cycle + + +# Sublists + +@docs splitAt, splitWhen, takeWhileRight, dropWhileRight, span, break, stripPrefix, group, groupWhile, groupWhileTransitively, inits, tails, select, selectSplit + + +# Predicates + +@docs isPrefixOf, isSuffixOf, isInfixOf, isSubsequenceOf, isPermutationOf + + +# Searching + +@docs notMember, find, elemIndex, elemIndices, findIndex, findIndices, count + + +# Zipping + +@docs zip, zip3, zip4, zip5 + + +# Lift functions onto multiple lists of arguments + +@docs lift2, lift3, lift4 + + +# Split to groups of given size + +@docs groupsOf, groupsOfWithStep, groupsOfVarying, greedyGroupsOf, greedyGroupsOfWithStep + +-} + +import List exposing (..) +import Set exposing (Set) +import Tuple exposing (first, second) + + +{-| Extract the last element of a list. + + last [1,2,3] == Just 3 + last [] == Nothing + +-} +last : List a -> Maybe a +last items = + case items of + [] -> + Nothing + + [ x ] -> + Just x + + _ :: rest -> + last rest + + +{-| Return all elements of the list except the last one. + + init [1,2,3] == Just [1,2] + init [] == Nothing + +-} +init : List a -> Maybe (List a) +init items = + case items of + [] -> + Nothing + + nonEmptyList -> + nonEmptyList + |> List.reverse + |> List.tail + |> Maybe.map List.reverse + + +{-| Returns `Just` the element at the given index in the list, +or `Nothing` if the index is out of range. +-} +getAt : Int -> List a -> Maybe a +getAt idx xs = + if idx < 0 then + Nothing + else + List.head <| List.drop idx xs + + +{-| Alias for getAt, but with the parameters flipped. +-} +(!!) : List a -> Int -> Maybe a +(!!) = + flip getAt + + +{-| Returns a list of repeated applications of `f`. If `f` returns `Nothing` +the iteration will stop. If it returns `Just y` then `y` will be added to the +list and the iteration will continue with `f y`. + + collatz : Int -> Maybe Int + collatz n = + if n == 1 then + Nothing + else + Just <| + if n % 2 == 0 then + n / 2 + else + 3 * n + 1 + + iterate collatz 13 == [13,40,20,10,5,16,8,4,2,1] + +-} +iterate : (a -> Maybe a) -> a -> List a +iterate f x = + case f x of + Just x_ -> + x :: iterate f x_ + + Nothing -> + [ x ] + + +{-| Initialize a list of some length with some function. + +`initialize n f` creates a list of length `n` with the element at index `i` initialized to the result of `f i`. + +-} +initialize : Int -> (Int -> a) -> List a +initialize n f = + let + step i acc = + if i < 0 then + acc + else + step (i - 1) (f i :: acc) + in + step (n - 1) [] + + +{-| Creates a list of the given length whose elements are obtained by cycling +through the elements of the given list. If the given list is empty, the +resulting list will be empty. + + cycle 6 [ 4, 7, 8 ] == [ 4, 7, 8, 4, 7, 8 ] + cycle 4 [ 'a', 'b', 'c' ] == [ 'a', 'b', 'c', 'a' ] + cycle 9001 [] == [] + cycle 2 [ 1, 2, 3, 4, 5 ] == [ 1, 2 ] + +-} +cycle : Int -> List a -> List a +cycle len list = + let + cycleLength = + List.length list + in + if cycleLength == 0 || cycleLength == len then + list + else if cycleLength < len then + List.reverse + (reverseAppend + (List.take (rem len cycleLength) list) + (cycleHelp [] (len // cycleLength) list) + ) + else + List.take len list + + +cycleHelp : List a -> Int -> List a -> List a +cycleHelp acc n list = + if n > 0 then + cycleHelp (reverseAppend list acc) (n - 1) list + else + acc + + +{-| Decompose a list into its head and tail. If the list is empty, return `Nothing`. Otherwise, return `Just (x, xs)`, where `x` is head and `xs` is tail. + + uncons [1,2,3] == Just (1, [2,3]) + uncons [] = Nothing + +-} +uncons : List a -> Maybe ( a, List a ) +uncons xs = + case xs of + [] -> + Nothing + + x :: xs -> + Just ( x, xs ) + + +{-| Find the first maximum element in a list using a comparable transformation +-} +maximumBy : (a -> comparable) -> List a -> Maybe a +maximumBy f ls = + let + maxBy x ( y, fy ) = + let + fx = + f x + in + if fx > fy then + ( x, fx ) + else + ( y, fy ) + in + case ls of + [ l_ ] -> + Just l_ + + l_ :: ls_ -> + Just <| first <| foldl maxBy ( l_, f l_ ) ls_ + + _ -> + Nothing + + +{-| Find the first minimum element in a list using a comparable transformation +-} +minimumBy : (a -> comparable) -> List a -> Maybe a +minimumBy f ls = + let + minBy x ( y, fy ) = + let + fx = + f x + in + if fx < fy then + ( x, fx ) + else + ( y, fy ) + in + case ls of + [ l_ ] -> + Just l_ + + l_ :: ls_ -> + Just <| first <| foldl minBy ( l_, f l_ ) ls_ + + _ -> + Nothing + + +{-| Take elements in order as long as the predicate evaluates to `True` +-} +takeWhile : (a -> Bool) -> List a -> List a +takeWhile predicate = + let + takeWhileMemo memo list = + case list of + [] -> + List.reverse memo + + x :: xs -> + if (predicate x) then + takeWhileMemo (x :: memo) xs + else + List.reverse memo + in + takeWhileMemo [] + + +{-| Drop elements in order as long as the predicate evaluates to `True` +-} +dropWhile : (a -> Bool) -> List a -> List a +dropWhile predicate list = + case list of + [] -> + [] + + x :: xs -> + if (predicate x) then + dropWhile predicate xs + else + list + + +{-| Remove duplicate values, keeping the first instance of each element which appears more than once. + + unique [0,1,1,0,1] == [0,1] + +-} +unique : List comparable -> List comparable +unique list = + uniqueHelp identity Set.empty list [] + + +{-| Drop duplicates where what is considered to be a duplicate is the result of first applying the supplied function to the elements of the list. +-} +uniqueBy : (a -> comparable) -> List a -> List a +uniqueBy f list = + uniqueHelp f Set.empty list [] + + +{-| Indicate if list has duplicate values. + + allDifferent [0,1,1,0,1] == False + +-} +allDifferent : List comparable -> Bool +allDifferent list = + allDifferentBy identity list + + +{-| Indicate if list has duplicate values when supplied function are applyed on each values. +-} +allDifferentBy : (a -> comparable) -> List a -> Bool +allDifferentBy f list = + List.length list == List.length (uniqueBy f list) + + +uniqueHelp : (a -> comparable) -> Set comparable -> List a -> List a -> List a +uniqueHelp f existing remaining accumulator = + case remaining of + [] -> + List.reverse accumulator + + first :: rest -> + let + computedFirst = + f first + in + if Set.member computedFirst existing then + uniqueHelp f existing rest accumulator + else + uniqueHelp f (Set.insert computedFirst existing) rest (first :: accumulator) + + +{-| Map functions taking multiple arguments over multiple lists. Each list should be of the same length. + + ((\a b c -> a + b * c) + |> flip map [1,2,3] + |> andMap [4,5,6] + |> andMap [2,1,1] + ) == [9,7,9] + +-} +andMap : List a -> List (a -> b) -> List b +andMap l fl = + map2 (<|) fl l + + +{-| Equivalent to `concatMap`. For example, suppose you want to have a cartesian product of [1,2] and [3,4]: + + [1,2] |> andThen (\x -> [3,4] + |> andThen (\y -> [(x,y)])) + +will give back the list: + + [(1,3),(1,4),(2,3),(2,4)] + +Now suppose we want to have a cartesian product between the first list and the second list and its doubles: + + [1,2] |> andThen (\x -> [3,4] + |> andThen (\y -> [y,y*2] + |> andThen (\z -> [(x,z)]))) + +will give back the list: + + [(1,3),(1,6),(1,4),(1,8),(2,3),(2,6),(2,4),(2,8)] + +Advanced functional programmers will recognize this as the implementation of bind operator (>>=) for lists from the `Monad` typeclass. + +-} +andThen : (a -> List b) -> List a -> List b +andThen = + concatMap + + +{-| `reverseMap f xs` gives the same result as `List.reverse (List.map f xs)`, +but is tail-recursive and slightly more efficient. + + reverseMap sqrt [1,4,9] == [3,2,1] + +-} +reverseMap : (a -> b) -> List a -> List b +reverseMap f xs = + foldl (\x acc -> f x :: acc) [] xs + + +{-| Negation of `member`. + + notMember 1 [1,2,3] == False + notMember 4 [1,2,3] == True + +-} +notMember : a -> List a -> Bool +notMember x = + not << member x + + +{-| Find the first element that satisfies a predicate and return +Just that element. If none match, return Nothing. + + find (\num -> num > 5) [2, 4, 6, 8] == Just 6 + +-} +find : (a -> Bool) -> List a -> Maybe a +find predicate list = + case list of + [] -> + Nothing + + first :: rest -> + if predicate first then + Just first + else + find predicate rest + + +{-| Return the index of the first occurrence of the element. Otherwise, return `Nothing`. Indexing starts from 0. + + elemIndex 1 [1,2,3] == Just 0 + elemIndex 4 [1,2,3] == Nothing + elemIndex 1 [1,2,1] == Just 0 + +-} +elemIndex : a -> List a -> Maybe Int +elemIndex x = + findIndex ((==) x) + + +{-| Return all indices of occurrences of the element. If element is not found, return empty list. Indexing starts from 0. + + elemIndices 1 [1,2,3] == [0] + elemIndices 4 [1,2,3] == [] + elemIndices 1 [1,2,1] == [0,2] + +-} +elemIndices : a -> List a -> List Int +elemIndices x = + findIndices ((==) x) + + +{-| Take a predicate and a list, return the index of the first element that satisfies the predicate. Otherwise, return `Nothing`. Indexing starts from 0. + + findIndex isEven [1,2,3] == Just 1 + findIndex isEven [1,3,5] == Nothing + findIndex isEven [1,2,4] == Just 1 + +-} +findIndex : (a -> Bool) -> List a -> Maybe Int +findIndex = + findIndexHelp 0 + + +findIndexHelp : Int -> (a -> Bool) -> List a -> Maybe Int +findIndexHelp index predicate list = + case list of + [] -> + Nothing + + x :: xs -> + if predicate x then + Just index + else + findIndexHelp (index + 1) predicate xs + + +{-| Take a predicate and a list, return indices of all elements satisfying the predicate. Otherwise, return empty list. Indexing starts from 0. + + findIndices isEven [1,2,3] == [1] + findIndices isEven [1,3,5] == [] + findIndices isEven [1,2,4] == [1,2] + +-} +findIndices : (a -> Bool) -> List a -> List Int +findIndices predicate = + let + consIndexIf index x acc = + if predicate x then + index :: acc + else + acc + in + indexedFoldr consIndexIf [] + + +{-| Returns the number of elements in a list that satisfy a given predicate. +Equivalent to `List.length (List.filter pred list)` but more efficient. + + count (\n -> n % 2 == 1) [1,2,3,4,5,6,7] == 4 + count ((==) "yeah") ["She","loves","you","yeah","yeah","yeah"] == 3 + +-} +count : (a -> Bool) -> List a -> Int +count predicate = + List.foldl + (\x acc -> + if predicate x then + acc + 1 + else + acc + ) + 0 + + +{-| Replace all values that satisfy a predicate with a replacement value. +-} +replaceIf : (a -> Bool) -> a -> List a -> List a +replaceIf predicate replacement list = + updateIf predicate (always replacement) list + + +{-| Replace all values that satisfy a predicate by calling an update function. +-} +updateIf : (a -> Bool) -> (a -> a) -> List a -> List a +updateIf predicate update list = + List.map + (\item -> + if predicate item then + update item + else + item + ) + list + + +{-| Replace a value at a specific index by calling an update function. Return the original list if the index is out of range. + + updateAt 0 ((+) 1) [ 1, 2, 3 ] == [ 2, 2, 3 ] + +See also `updateIfIndex`. + +-} +updateAt : Int -> (a -> a) -> List a -> List a +updateAt index fn list = + if index < 0 then + list + else + let + head = + List.take index list + + tail = + List.drop index list + in + case tail of + x :: xs -> + head ++ fn x :: xs + + _ -> + list + + +{-| Replace a value at an index that satisfies a predicate, by calling an update function. + + updateIfIndex ((==) 2) ((+) 1) [ 1, 2, 3 ] == [ 1, 2, 4 ] + +See also `updateAt`. + +-} +updateIfIndex : (Int -> Bool) -> (a -> a) -> List a -> List a +updateIfIndex predicate update list = + List.indexedMap + (\i x -> + if predicate i then + update x + else + x + ) + list + + +{-| Remove the first occurrence of a value from a list. +-} +remove : a -> List a -> List a +remove x xs = + case xs of + [] -> + [] + + y :: ys -> + if x == y then + ys + else + y :: remove x ys + + +{-| Set a value in a list by index. Return the original list if the index is out of range. + + setAt 0 42 [ 1, 2, 3 ] == [ 42, 2, 3 ] + +-} +setAt : Int -> a -> List a -> List a +setAt index value = + updateAt index (always value) + + +{-| Similar to List.sortWith, this sorts values with a custom comparison function. +Unlike List.sortWith, this sort is guaranteed to be a stable sort. +Note that List.sortWith is faster and is preferred if sort stability is not required. +-} +stableSortWith : (a -> a -> Basics.Order) -> List a -> List a +stableSortWith pred list = + let + listWithIndex = + List.indexedMap (\i a -> ( a, i )) list + + predWithIndex ( a1, i1 ) ( a2, i2 ) = + let + result = + pred a1 a2 + in + case result of + Basics.EQ -> + Basics.compare i1 i2 + + _ -> + result + in + List.sortWith predWithIndex listWithIndex |> List.map first + + +{-| Swap two values in a list by index. Return the original list if the index is out of range. +If the same index is supplied twice the operation has no effect. + + swapAt 1 2 [ 1, 2, 3 ] == [ 1, 3, 2 ] + +-} +swapAt : Int -> Int -> List a -> List a +swapAt index1 index2 l = + if index1 == index2 || index1 < 0 then + l + else if index1 > index2 then + swapAt index2 index1 l + else + let + ( part1, tail1 ) = + splitAt index1 l + + ( head2, tail2 ) = + splitAt (index2 - index1) tail1 + in + case ( uncons head2, uncons tail2 ) of + ( Just ( value1, part2 ), Just ( value2, part3 ) ) -> + List.concat [ part1, value2 :: part2, value1 :: part3 ] + + _ -> + l + + +{-| Remove the element at an index from a list. Return the original list if the index is out of range. + + removeAt 0 [ 1, 2, 3 ] == [ 2, 3 ] + +See also `removeIfIndex`. + +-} +removeAt : Int -> List a -> List a +removeAt index l = + if index < 0 then + l + else + let + head = + List.take index l + + tail = + List.drop index l |> List.tail + in + case tail of + Nothing -> + l + + Just t -> + List.append head t + + +{-| Remove an element at an index that satisfies a predicate. + + removeIfIndex ((==) 2) [ 1, 2, 3 ] == [ 1, 2 ] + +See also `removeAt`. + +-} +removeIfIndex : (Int -> Bool) -> List a -> List a +removeIfIndex predicate = + indexedFoldr + (\index item acc -> + if predicate index then + acc + else + item :: acc + ) + [] + + +{-| Take a predicate and a list, and return a list that contains elements which fails to satisfy the predicate. +This is equivalent to `List.filter (not << predicate) list`. + + filterNot isEven [1,2,3,4] == [1,3] + +-} +filterNot : (a -> Bool) -> List a -> List a +filterNot pred list = + List.filter (not << pred) list + + +{-| Take a list and a list of lists, insert that list between every list in the list of lists, concatenate the result. `intercalate xs xss` is equivalent to `concat (intersperse xs xss)`. + + intercalate [0,0] [[1,2],[3,4],[5,6]] == [1,2,0,0,3,4,0,0,5,6] + +-} +intercalate : List a -> List (List a) -> List a +intercalate xs = + concat << intersperse xs + + +{-| Transpose rows and columns of the list of lists. + + transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]] + +If some rows are shorter than the following rows, their elements are skipped: + + transpose [[10,11],[20],[],[30,31,32]] == [[10,20,30],[11,31],[32]] + +-} +transpose : List (List a) -> List (List a) +transpose listOfLists = + List.foldr (List.map2 (::)) (List.repeat (rowsLength listOfLists) []) listOfLists + + +rowsLength : List (List a) -> Int +rowsLength listOfLists = + case listOfLists of + [] -> + 0 + + x :: _ -> + List.length x + + +{-| Return the list of all subsequences of a list. + + subsequences [1,2,3] == [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] + +-} +subsequences : List a -> List (List a) +subsequences xs = + [] :: subsequencesNonEmpty xs + + +{-| Return the list of all subsequences of the argument, except for the empty list. + + subsequencesNonEmpty [1,2,3] == [[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] + +-} +subsequencesNonEmpty : List a -> List (List a) +subsequencesNonEmpty xs = + case xs of + [] -> + [] + + x :: xs -> + let + f ys r = + ys :: (x :: ys) :: r + in + [ x ] :: foldr f [] (subsequencesNonEmpty xs) + + +{-| Return the list of of all permutations of a list. The result is in lexicographic order. + + permutations [1,2,3] == [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] + +-} +permutations : List a -> List (List a) +permutations xs_ = + case xs_ of + [] -> + [ [] ] + + xs -> + let + f ( y, ys ) = + map ((::) y) (permutations ys) + in + concatMap f (select xs) + + +{-| Return a list that contains elements from the two provided, in alternate order. +If one list runs out of items, append the items from the remaining list. + + interweave [1,3] [2,4] == [1,2,3,4] + interweave [1,3,5,7] [2,4] == [1,2,3,4,5,7] + interweave [4,9,16] [2,3,5,7] == [4,2,9,3,16,5,7] + +-} +interweave : List a -> List a -> List a +interweave = + interweaveHelp [] + + +interweaveHelp : List a -> List a -> List a -> List a +interweaveHelp acc list1 list2 = + case ( list1, list2 ) of + ( x :: xs, y :: ys ) -> + interweaveHelp (y :: x :: acc) xs ys + + ( [], _ ) -> + reverseAppend acc list2 + + ( _, [] ) -> + reverseAppend acc list1 + + +{-| Return the cartesian product of a list of lists. +If one list is empty, the result is an empty list. +If the list of lists is empty, the result is an empty singleton. + + cartesianProduct [[1,2],[3,4,5],[6]] == [[1,3,6],[1,4,6],[1,5,6],[2,3,6],[2,4,6],[2,5,6]] + cartesianProduct [[1,2]] == [[1],[2]] + cartesianProduct [[1,2],[],[6]] == [] + cartesianProduct [[]] == [] + cartesianProduct [] == [[]] + +-} +cartesianProduct : List (List a) -> List (List a) +cartesianProduct ll = + case ll of + [] -> + [ [] ] + + xs :: xss -> + lift2 (::) xs (cartesianProduct xss) + + +reverseAppend : List a -> List a -> List a +reverseAppend list1 list2 = + List.foldl (::) list2 list1 + + +{-| Variant of `foldl` that has no starting value argument and treats the head of the list as its starting value. If the list is empty, return `Nothing`. + + foldl1 max [1,2,3,2,1] == Just 3 + foldl1 max [] == Nothing + foldl1 (-) [1,2,3] == Just -4 + +-} +foldl1 : (a -> a -> a) -> List a -> Maybe a +foldl1 f xs = + let + mf x m = + Just + (case m of + Nothing -> + x + + Just y -> + f y x + ) + in + List.foldl mf Nothing xs + + +{-| Variant of `foldr` that has no starting value argument and treats the last element of the list as its starting value. If the list is empty, return `Nothing`. + + foldr1 min [1,2,3,2,1] == Just 1 + foldr1 min [] == Nothing + foldr1 (-) [1,2,3] == Just 2 + +-} +foldr1 : (a -> a -> a) -> List a -> Maybe a +foldr1 f xs = + let + mf x m = + Just + (case m of + Nothing -> + x + + Just y -> + f x y + ) + in + List.foldr mf Nothing xs + + +{-| Variant of `foldl` that passes the index of the current element to the step function. `indexedFoldl` is to `List.foldl` as `List.indexedMap` is to `List.map`. +-} +indexedFoldl : (Int -> a -> b -> b) -> b -> List a -> b +indexedFoldl func acc list = + let + step x ( i, acc ) = + ( i + 1, func i x acc ) + in + second (List.foldl step ( 0, acc ) list) + + +{-| Variant of `foldr` that passes the index of the current element to the step function. `indexedFoldr` is to `List.foldr` as `List.indexedMap` is to `List.map`. +-} +indexedFoldr : (Int -> a -> b -> b) -> b -> List a -> b +indexedFoldr func acc list = + let + step x ( i, acc ) = + ( i - 1, func i x acc ) + in + second (List.foldr step ( List.length list - 1, acc ) list) + + +{-| `scanl1` is a variant of `scanl` that has no starting value argument. + +Compare: + + List.scanl (+) 0 [1,2,3] == [0,1,3,6] + scanl1 (+) [1,2,3] == [1,3,6] + + List.scanl (-) 0 [1,2,3] == [0,1,1,2] + scanl1 (-) [1,2,3] == [1,1,2] + + List.scanl (flip (-)) 0 [1,2,3] == [0,-1,-3,-6] + scanl1 (flip (-)) [1,2,3] == [1,-1,-4] + +-} +scanl1 : (a -> a -> a) -> List a -> List a +scanl1 f xs_ = + case xs_ of + [] -> + [] + + x :: xs -> + scanl f x xs + + +{-| `scanr` is a right-to-left dual of `scanl`. Note that: + + head (scanr f z xs) == foldr f z xs + +Examples: + + scanr (+) 0 [1,2,3] == [6,5,3,0] + scanr (-) 0 [1,2,3] == [2,-1,3,0] + +-} +scanr : (a -> b -> b) -> b -> List a -> List b +scanr f acc xs_ = + case xs_ of + [] -> + [ acc ] + + x :: xs -> + case scanr f acc xs of + (q :: _) as qs -> + f x q :: qs + + [] -> + [] + + +{-| `scanr1` is a variant of `scanr` that has no starting value argument. + + scanr1 (+) [1,2,3] == [6,5,3] + scanr1 (-) [1,2,3] == [2,-1,3] + scanr1 (flip (-)) [1,2,3] == [0,1,3] + +-} +scanr1 : (a -> a -> a) -> List a -> List a +scanr1 f xs_ = + case xs_ of + [] -> + [] + + [ x ] -> + [ x ] + + x :: xs -> + case scanr1 f xs of + (q :: _) as qs -> + f x q :: qs + + [] -> + [] + + +{-| The mapAccuml function behaves like a combination of map and foldl; it applies a +function to each element of a list, passing an accumulating parameter from left to right, +and returning a final value of this accumulator together with the new list. + + mapAccuml f a0 [ x1, x2, x3 ] == ( a3, [ y1, y2, y3 ] ) + + -- x1 x2 x3 + -- | | | + -- a0 -- f --- f --- f -> a3 + -- | | | + -- y1 y2 y3 + +Add a running total to a list of numbers: + + mapAccuml (\a x -> ( a + x, ( x, a + x ) )) 0 [ 2, 4, 8 ] + == ( 14, [ ( 2, 2 ), ( 4, 6 ), ( 8, 14 ) ] ) + +Map number by multiplying with accumulated sum: + + mapAccuml (\a x -> ( a + x, a * x )) 5 [ 2, 4, 8 ] + == ( 19, [ 10, 28, 88 ] ) + +-} +mapAccuml : (a -> b -> ( a, c )) -> a -> List b -> ( a, List c ) +mapAccuml f acc0 list = + let + ( accFinal, generatedList ) = + List.foldl + (\x ( acc1, ys ) -> + let + ( acc2, y ) = + f acc1 x + in + ( acc2, y :: ys ) + ) + ( acc0, [] ) + list + in + ( accFinal, List.reverse generatedList ) + + +{-| The mapAccumr function behaves like a combination of map and foldr; it applies a +function to each element of a list, passing an accumulating parameter from right to left, +and returning a final value of this accumulator together with the new list. + + mapAccumr f a0 [ x1, x2, x3 ] == ( a3, [ y1, y2, y3 ] ) + + -- x1 x2 x3 + -- | | | + -- a3 <- f --- f --- f -- a0 + -- | | | + -- y1 y2 y3 + +Add a count of remaining elements: + + mapAccumr (\a x -> ( a + 1, ( x, a ) )) 0 [ 2, 4, 8 ] + == ( 3, [ ( 2, 2 ), ( 4, 1 ), ( 8, 0 ) ] ) + +Map number by multiplying with right-to-left accumulated sum: + + mapAccumr (\a x -> ( a + x, a * x )) 5 [ 2, 4, 8 ] + == ( 19, [ 34, 52, 40 ] ) + +-} +mapAccumr : (a -> b -> ( a, c )) -> a -> List b -> ( a, List c ) +mapAccumr f acc0 list = + List.foldr + (\x ( acc1, ys ) -> + let + ( acc2, y ) = + f acc1 x + in + ( acc2, y :: ys ) + ) + ( acc0, [] ) + list + + +{-| The `unfoldr` function is "dual" to `foldr`. `foldr` reduces a list to a summary value, `unfoldr` builds a list from a seed. The function takes a function and a starting element. It applies the function to the element. If the result is `Just (a, b)`, `a` is accumulated and the function is applied to `b`. If the result is `Nothing`, the list accumulated so far is returned. + + unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 5 == [5,4,3,2,1] + +-} +unfoldr : (b -> Maybe ( a, b )) -> b -> List a +unfoldr f seed = + case f seed of + Nothing -> + [] + + Just ( a, b ) -> + a :: unfoldr f b + + +{-| Take a number and a list, return a tuple of lists, where first part is prefix of the list of length equal the number, and second part is the remainder of the list. `splitAt n xs` is equivalent to `(take n xs, drop n xs)`. + + splitAt 3 [1,2,3,4,5] == ([1,2,3],[4,5]) + splitAt 1 [1,2,3] == ([1],[2,3]) + splitAt 3 [1,2,3] == ([1,2,3],[]) + splitAt 4 [1,2,3] == ([1,2,3],[]) + splitAt 0 [1,2,3] == ([],[1,2,3]) + splitAt (-1) [1,2,3] == ([],[1,2,3]) + +-} +splitAt : Int -> List a -> ( List a, List a ) +splitAt n xs = + ( take n xs, drop n xs ) + + +{-| Attempts to split the list at the first element where the given predicate is true. If the predicate is not true for any elements in the list, return nothing. Otherwise, return the split list. + + splitWhen (\n -> n == 3) [1,2,3,4,5] == Just ([1,2],[3,4,5]) + splitWhen (\n -> n == 6) [1,2,3,4,5] == Nothing + +-} +splitWhen : (a -> Bool) -> List a -> Maybe ( List a, List a ) +splitWhen predicate list = + findIndex predicate list + |> Maybe.map (\i -> splitAt i list) + + +{-| Take elements from the right, while predicate still holds. + + takeWhileRight ((<)5) (range 1 10) == [6,7,8,9,10] + +-} +takeWhileRight : (a -> Bool) -> List a -> List a +takeWhileRight p = + let + step x ( xs, free ) = + if p x && free then + ( x :: xs, True ) + else + ( xs, False ) + in + first << foldr step ( [], True ) + + +{-| Drop elements from the right, while predicate still holds. + + dropWhileRight ((<)5) (range 1 10) == [1,2,3,4,5] + +-} +dropWhileRight : (a -> Bool) -> List a -> List a +dropWhileRight p = + foldr + (\x xs -> + if p x && isEmpty xs then + [] + else + x :: xs + ) + [] + + +{-| Take a predicate and a list, return a tuple. The first part of the tuple is the longest prefix of that list, for each element of which the predicate holds. The second part of the tuple is the remainder of the list. `span p xs` is equivalent to `(takeWhile p xs, dropWhile p xs)`. + + span ((>) 3) [1,2,3,4,1,2,3,4] == ([1,2],[3,4,1,2,3,4]) + span ((>) 5) [1,2,3] == ([1,2,3],[]) + span ((>) 0) [1,2,3] == ([],[1,2,3]) + +-} +span : (a -> Bool) -> List a -> ( List a, List a ) +span p xs = + ( takeWhile p xs, dropWhile p xs ) + + +{-| Take a predicate and a list, return a tuple. The first part of the tuple is the longest prefix of that list, for each element of which the predicate *does not* hold. The second part of the tuple is the remainder of the list. `break p xs` is equivalent to `(takeWhile (not p) xs, dropWhile (not p) xs)`. + + break ((<) 3) [1,2,3,4,1,2,3,4] == ([1,2,3],[4,1,2,3,4]) + break ((>) 5) [1,2,3] == ([],[1,2,3]) + break ((<) 5) [1,2,3] == ([1,2,3],[]) + +-} +break : (a -> Bool) -> List a -> ( List a, List a ) +break p = + span (not << p) + + +{-| Drop the given prefix from the list. If the list doesn't start with that prefix, return `Nothing`. + + stripPrefix [1,2] [1,2,3,4] == Just [3,4] + stripPrefix [1,2,3] [1,2,3,4,5] == Just [4,5] + stripPrefix [1,2,3] [1,2,3] == Just [] + stripPrefix [1,2,3] [1,2] == Nothing + stripPrefix [3,2,1] [1,2,3,4,5] == Nothing + +-} +stripPrefix : List a -> List a -> Maybe (List a) +stripPrefix prefix xs = + let + step e m = + case m of + Nothing -> + Nothing + + Just [] -> + Nothing + + Just (x :: xs_) -> + if e == x then + Just xs_ + else + Nothing + in + foldl step (Just xs) prefix + + +{-| Group similar elements together. `group` is equivalent to `groupWhile (==)`. + + group [1,2,2,3,3,3,2,2,1] == [[1],[2,2],[3,3,3],[2,2],[1]] + +-} +group : List a -> List (List a) +group = + groupWhile (==) + + +{-| Group elements together, using a custom equality test. + + groupWhile (\x y -> first x == first y) [(0,'a'),(0,'b'),(1,'c'),(1,'d')] == [[(0,'a'),(0,'b')],[(1,'c'),(1,'d')]] + +The equality test should be an [equivalence relation](https://en.wikipedia.org/wiki/Equivalence_relation), i.e. it should have the properties: + + - Reflexivity - Testing an object against itself returns `True`. + - Symmetry - Testing two objects should give the same result regardless of the order they are passed. + - Transitivity - If the test on a first object and a second object results in `True`, and further if the test on that second object and a third also results in `True`, then the test should result in `True` when the first and third objects are passed. + +For non-equivalent relations `groupWhile` has non-intuitive behavior. For example, inequality comparisons like `(<)` are not equivalence relations, so do *not* write `groupWhile (<) [1,3,5,2,4]`, as it will give an unexpected answer. + +For grouping elements with a comparison test which is merely transitive, such as `(<)` or `(<=)`, see `groupWhileTransitively`. + +-} +groupWhile : (a -> a -> Bool) -> List a -> List (List a) +groupWhile eq xs_ = + case xs_ of + [] -> + [] + + x :: xs -> + let + ( ys, zs ) = + span (eq x) xs + in + (x :: ys) :: groupWhile eq zs + + +{-| Group elements together, using a custom comparison test. Start a new group each time the comparison test doesn't hold for two adjacent elements. + + groupWhileTransitively (<) [1,2,3,2,4,1,3,2,1] == [[1,2,3],[2,4],[1,3],[2],[1]] + +-} +groupWhileTransitively : (a -> a -> Bool) -> List a -> List (List a) +groupWhileTransitively compare list = + groupWhileTransitivelyHelp [] [] compare list + + +groupWhileTransitivelyHelp : List (List a) -> List a -> (a -> a -> Bool) -> List a -> List (List a) +groupWhileTransitivelyHelp result currentGroup compare list = + case list of + [] -> + List.reverse <| + if List.isEmpty currentGroup then + result + else + List.reverse (currentGroup :: result) + + [ x ] -> + List.reverse <| + (List.reverse (x :: currentGroup) :: result) + + first :: ((second :: _) as rest) -> + if compare first second then + groupWhileTransitivelyHelp + result + (first :: currentGroup) + compare + rest + else + groupWhileTransitivelyHelp + (List.reverse (first :: currentGroup) :: result) + [] + compare + rest + + +{-| Return all initial segments of a list, from shortest to longest, empty list first, the list itself last. + + inits [1,2,3] == [[],[1],[1,2],[1,2,3]] + +-} +inits : List a -> List (List a) +inits = + foldr (\e acc -> [] :: map ((::) e) acc) [ [] ] + + +{-| Return all final segments of a list, from longest to shortest, the list itself first, empty list last. + + tails [1,2,3] == [[1,2,3],[2,3],[3],[]] + +-} +tails : List a -> List (List a) +tails = + foldr tailsHelp [ [] ] + + +tailsHelp : a -> List (List a) -> List (List a) +tailsHelp e list = + case list of + x :: xs -> + (e :: x) :: x :: xs + + [] -> + [] + + +{-| Return all combinations in the form of (element, rest of the list). Read [Haskell Libraries proposal](https://mail.haskell.org/pipermail/libraries/2008-February/009270.html) for further ideas on how to use this function. + + select [1,2,3,4] == [(1,[2,3,4]),(2,[1,3,4]),(3,[1,2,4]),(4,[1,2,3])] + +-} +select : List a -> List ( a, List a ) +select xs = + case xs of + [] -> + [] + + x :: xs -> + ( x, xs ) :: map (\( y, ys ) -> ( y, x :: ys )) (select xs) + + +{-| Return all combinations in the form of (elements before, element, elements after). + + selectSplit [1,2,3] == [([],1,[2,3]),([1],2,[3]),([1,2],3,[])] + +-} +selectSplit : List a -> List ( List a, a, List a ) +selectSplit xs = + case xs of + [] -> + [] + + x :: xs -> + ( [], x, xs ) :: map (\( lys, y, rys ) -> ( x :: lys, y, rys )) (selectSplit xs) + + +{-| Take two lists and return `True`, if the first list is the prefix of the second list. +-} +isPrefixOf : List a -> List a -> Bool +isPrefixOf prefix xs = + case ( prefix, xs ) of + ( [], _ ) -> + True + + ( _ :: _, [] ) -> + False + + ( p :: ps, x :: xs ) -> + p == x && isPrefixOf ps xs + + +{-| Take two lists and return `True`, if the first list is the suffix of the second list. +-} +isSuffixOf : List a -> List a -> Bool +isSuffixOf suffix xs = + isPrefixOf (reverse suffix) (reverse xs) + + +{-| Return True if all the elements of the first list occur in-order and +consecutively anywhere within the second. + + isInfixOf [5, 7, 11] [2, 3, 5, 7, 11, 13] == True + isInfixOf [5, 7, 13] [2, 3, 5, 7, 11, 13] == False + isInfixOf [3, 5, 2] [2, 3, 5, 7, 11, 13] == False + +-} +isInfixOf : List a -> List a -> Bool +isInfixOf infixList list = + case infixList of + [] -> + True + + x :: xs -> + isInfixOfHelp x xs list + + +isInfixOfHelp : a -> List a -> List a -> Bool +isInfixOfHelp infixHead infixTail list = + case list of + [] -> + False + + x :: xs -> + if x == infixHead then + isPrefixOf infixTail xs + else + isInfixOfHelp infixHead infixTail xs + + +{-| Return True if all the elements of the first list occur, in order, in the +second. The elements do not have to occur consecutively. + + isSubsequenceOf ["E", "l", "m"] ["E", "a", "t", " ", "l", "i", "m", "e", "s"] == True + isSubsequenceOf ["E", "l", "m"] ["E", "m", "a", "i", "l"] == False + +-} +isSubsequenceOf : List a -> List a -> Bool +isSubsequenceOf subseq list = + case ( subseq, list ) of + ( [], _ ) -> + True + + ( _, [] ) -> + False + + ( x :: xs, y :: ys ) -> + if x == y then + isSubsequenceOf xs ys + else + isSubsequenceOf subseq ys + + +{-| Take two lists and return `True`, if the first list is a permutation of the second list. +-} +isPermutationOf : List a -> List a -> Bool +isPermutationOf permut xs = + member permut (permutations xs) + + +{-| Take two lists and returns a list of corresponding pairs +-} +zip : List a -> List b -> List ( a, b ) +zip = + map2 (,) + + +{-| Take three lists and returns a list of triples +-} +zip3 : List a -> List b -> List c -> List ( a, b, c ) +zip3 = + map3 (,,) + + +{-| Take four lists and returns a list of quadruples +-} +zip4 : List a -> List b -> List c -> List d -> List ( a, b, c, d ) +zip4 = + map4 (,,,) + + +{-| Take five lists and returns a list of quintuples +-} +zip5 : List a -> List b -> List c -> List d -> List e -> List ( a, b, c, d, e ) +zip5 = + map5 (,,,,) + + +{-| Map functions taking multiple arguments over multiple lists, regardless of list length. +All possible combinations will be explored. + +lift2 (+) [1,2,3][4,5] == [5,6,6,7,7,8] + +-} +lift2 : (a -> b -> c) -> List a -> List b -> List c +lift2 f la lb = + la |> andThen (\a -> lb |> andThen (\b -> [ f a b ])) + + +{-| -} +lift3 : (a -> b -> c -> d) -> List a -> List b -> List c -> List d +lift3 f la lb lc = + la |> andThen (\a -> lb |> andThen (\b -> lc |> andThen (\c -> [ f a b c ]))) + + +{-| -} +lift4 : (a -> b -> c -> d -> e) -> List a -> List b -> List c -> List d -> List e +lift4 f la lb lc ld = + la |> andThen (\a -> lb |> andThen (\b -> lc |> andThen (\c -> ld |> andThen (\d -> [ f a b c d ])))) + + +{-| Split list into groups of length `size`. If there are not enough elements +to completely fill the last group, it will not be included. This is equivalent +to calling `groupsOfWithStep` with the same `size` and `step`. + + groupsOf 3 (range 1 10) == [[1,2,3],[4,5,6],[7,8,9]] + +-} +groupsOf : Int -> List a -> List (List a) +groupsOf size xs = + groupsOfWithStep size size xs + + +{-| Split list into groups of length `size` at offsets `step` apart. If there +are not enough elements to completely fill the last group, it will not be +included. (See `greedyGroupsOfWithStep` if you would like the last group to be +included regardless.) + + groupsOfWithStep 4 4 (range 1 10) == [[1,2,3,4],[5,6,7,8]] + groupsOfWithStep 3 1 (range 1 5) == [[1,2,3],[2,3,4],[3,4,5]] + groupsOfWithStep 3 6 (range 1 20) == [[1,2,3],[7,8,9],[13,14,15]] + +If `step == size`, every element (except for perhaps the last few due to the +non-greedy behavior) will appear in exactly one group. If `step < size`, there +will be an overlap between groups. If `step > size`, some elements will be +skipped and not appear in any groups. + +-} +groupsOfWithStep : Int -> Int -> List a -> List (List a) +groupsOfWithStep size step xs = + let + group = + List.take size xs + + xs_ = + List.drop step xs + + okayArgs = + size > 0 && step > 0 + + okayLength = + size == List.length group + in + if okayArgs && okayLength then + group :: groupsOfWithStep size step xs_ + else + [] + + +{-| `groupsOfVarying ns` takes `n` elements from a list for each `n` in `ns`, splitting the list into variably sized segments + + groupsOfVarying [2, 3, 1] ["a", "b", "c", "d", "e", "f"] == [["a", "b"], ["c", "d", "e"], ["f"]] + groupsOfVarying [2] ["a", "b", "c", "d", "e", "f"] == [["a", "b"]] + groupsOfVarying [2, 3, 1, 5, 6] ["a", "b", "c", "d", "e"] == [["a", "b"], ["c", "d", "e"]] + +-} +groupsOfVarying : List Int -> List a -> List (List a) +groupsOfVarying listOflengths list = + groupsOfVarying_ listOflengths list [] + + +groupsOfVarying_ : List Int -> List a -> List (List a) -> List (List a) +groupsOfVarying_ listOflengths list accu = + case ( listOflengths, list ) of + ( length :: tailLengths, _ :: _ ) -> + let + ( head, tail ) = + splitAt length list + in + groupsOfVarying_ tailLengths tail (head :: accu) + + _ -> + List.reverse accu + + +{-| Greedily split list into groups of length `size`. The last group of +elements will be included regardless of whether there are enough elements in +the list to completely fill it. This is equivalent to calling +`greedyGroupsOfWithStep` with the same `size` and `step`. + + greedyGroupsOf 3 (range 1 10) == [[1,2,3],[4,5,6],[7,8,9],[10]] + +-} +greedyGroupsOf : Int -> List a -> List (List a) +greedyGroupsOf size xs = + greedyGroupsOfWithStep size size xs + + +{-| Greedily split list into groups of length `size` at offsets `step` apart. +The last group of elements will be included regardless of whether there are +enough elements in the list to completely fill it. (See `groupsOfWithStep` +for the non-greedy version of this function). + + greedyGroupsOfWithStep 4 4 (range 1 10) == [[1,2,3,4],[5,6,7,8],[9,10]] + greedyGroupsOfWithStep 3 2 (range 1 6) == [[1,2,3],[3,4,5],[5,6]] + greedyGroupsOfWithStep 3 6 (range 1 20) == [[1,2,3],[7,8,9],[13,14,15],[19,20]] + +If `step == size`, every element will appear in exactly one group. If +`step < size`, there will be an overlap between groups. If `step > size`, some +elements will be skipped and not appear in any groups. + +-} +greedyGroupsOfWithStep : Int -> Int -> List a -> List (List a) +greedyGroupsOfWithStep size step xs = + let + group = + List.take size xs + + xs_ = + List.drop step xs + + okayArgs = + size > 0 && step > 0 + + okayXs = + List.length xs > 0 + in + if okayArgs && okayXs then + group :: greedyGroupsOfWithStep size step xs_ + else + [] diff --git a/client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/.gitignore b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/.gitignore new file mode 100644 index 0000000..aee9810 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/.gitignore @@ -0,0 +1 @@ +/elm-stuff/ diff --git a/client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/Tests.elm b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/Tests.elm new file mode 100644 index 0000000..7e6a221 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/Tests.elm @@ -0,0 +1,676 @@ +module Tests exposing (..) + +import Test exposing (..) +import Expect +import Fuzz exposing (list, int, tuple3) +import List exposing (map, range) +import Tuple exposing (first) +import List.Extra exposing (..) + + +all : Test +all = + describe "List.Extra" + [ describe "unique" <| + [ test "removes duplicates" <| + \() -> + Expect.equal (List.Extra.unique [ 0, 1, 1, 0, 1 ]) [ 0, 1 ] + , test "preserves list order" <| + \() -> + Expect.equal (List.Extra.unique [ 3, 3, 2, 1, 1, 0 ]) [ 3, 2, 1, 0 ] + ] + , describe "allDifferent" <| + [ test "detects duplicates" <| + \() -> + Expect.equal (List.Extra.allDifferent [ 0, 1, 1, 0, 1 ]) False + ] + , describe "andMap" <| + [ test "computes piecemeal" <| + \() -> + Expect.equal + ([ 1, 2, 3 ] + |> map (\a b c -> a + b * c) + |> andMap [ 4, 5, 6 ] + |> andMap [ 2, 1, 1 ] + ) + [ 9, 7, 9 ] + ] + , describe "reverseMap" <| + [ test "maps and reverses" <| + \() -> + Expect.equal (reverseMap sqrt [ 1, 4, 9 ]) [ 3, 2, 1 ] + ] + , describe "notMember" <| + [ test "disconfirms member" <| + \() -> + Expect.equal (notMember 1 [ 1, 2, 3 ]) False + , test "confirms non-member" <| + \() -> + Expect.equal (notMember 4 [ 1, 2, 3 ]) True + ] + , describe "find" <| + [ test "behaves as documented" <| + \() -> + Expect.equal (find (\num -> num > 5) [ 2, 4, 6, 8 ]) (Just 6) + ] + , describe "elemIndex" <| + [ test "finds index of value" <| + \() -> + Expect.equal (elemIndex 1 [ 1, 2, 3 ]) (Just 0) + , test "doesn't find index of non-present" <| + \() -> + Expect.equal (elemIndex 4 [ 1, 2, 3 ]) Nothing + , test "finds index of first match" <| + \() -> + Expect.equal (elemIndex 1 [ 1, 2, 1 ]) (Just 0) + ] + , describe "elemIndices" <| + [ test "finds singleton index" <| + \() -> + Expect.equal (elemIndices 1 [ 1, 2, 3 ]) [ 0 ] + , test "doesn't find indices of non-present" <| + \() -> + Expect.equal (elemIndices 4 [ 1, 2, 3 ]) [] + , test "finds all indices" <| + \() -> + Expect.equal (elemIndices 1 [ 1, 2, 1 ]) [ 0, 2 ] + ] + , describe "findIndex" <| + [ test "finds index of value" <| + \() -> + Expect.equal (findIndex (\x -> x % 2 == 0) [ 1, 2, 3 ]) (Just 1) + , test "doesn't find index of non-present" <| + \() -> + Expect.equal (findIndex (\x -> x % 2 == 0) [ 1, 3, 5 ]) Nothing + , test "finds index of first match" <| + \() -> + Expect.equal (findIndex (\x -> x % 2 == 0) [ 1, 2, 4 ]) (Just 1) + ] + , describe "findIndices" <| + [ test "finds singleton index" <| + \() -> + Expect.equal (findIndices (\x -> x % 2 == 0) [ 1, 2, 3 ]) [ 1 ] + , test "doesn't find indices of non-present" <| + \() -> + Expect.equal (findIndices (\x -> x % 2 == 0) [ 1, 3, 5 ]) [] + , test "finds all indices" <| + \() -> + Expect.equal (findIndices (\x -> x % 2 == 0) [ 1, 2, 4 ]) [ 1, 2 ] + ] + , describe "count" <| + [ test "isOdd predicate" <| + \() -> + Expect.equal (count (\n -> n % 2 == 1) [ 1, 2, 3, 4, 5, 6, 7 ]) 4 + , test "equal predicate" <| + \() -> + Expect.equal (count ((==) "yeah") [ "She", "loves", "you", "yeah", "yeah", "yeah" ]) 3 + ] + , describe "intercalate" <| + [ test "computes example" <| + \() -> + Expect.equal + (intercalate [ 0, 0 ] [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ]) + [ 1, 2, 0, 0, 3, 4, 0, 0, 5, 6 ] + ] + , describe "transpose" <| + [ test "performs basic transpose" <| + \() -> + Expect.equal + (transpose [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]) + [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ] + , test "truncate the matrix to the shortest row size" <| + \() -> + Expect.equal + (transpose [ [ 10, 11 ], [ 20 ], [ 30, 31, 32 ] ]) + [ [ 10, 20, 30 ] ] + , test "transposes large lists" <| + \() -> + Expect.equal + (transpose [ List.repeat 10000 1 ]) + (List.repeat 10000 [ 1 ]) + ] + , describe "subsequences" <| + [ test "computes subsequences" <| + \() -> + Expect.equal + (subsequences [ 1, 2, 3 ]) + [ [], [ 1 ], [ 2 ], [ 1, 2 ], [ 3 ], [ 1, 3 ], [ 2, 3 ], [ 1, 2, 3 ] ] + ] + , describe "permutations" <| + [ test "computes permutations" <| + \() -> + Expect.equal + (permutations [ 1, 2, 3 ]) + [ [ 1, 2, 3 ], [ 1, 3, 2 ], [ 2, 1, 3 ], [ 2, 3, 1 ], [ 3, 1, 2 ], [ 3, 2, 1 ] ] + ] + , describe "interweave" <| + [ test "interweaves lists of equal length" <| + \() -> + Expect.equal (interweave [ 1, 3 ] [ 2, 4 ]) [ 1, 2, 3, 4 ] + , test "appends remaining members of first list, if longer" <| + \() -> + Expect.equal (interweave [ 1, 3, 5, 7 ] [ 2, 4 ]) [ 1, 2, 3, 4, 5, 7 ] + , test "appends remaining members of second list, if longer" <| + \() -> + Expect.equal (interweave [ 4, 9, 16 ] [ 2, 3, 5, 7 ]) [ 4, 2, 9, 3, 16, 5, 7 ] + ] + , describe "cartesianProduct" <| + [ test "computes the cartesian product of lists of different length" <| + \() -> + Expect.equal (cartesianProduct [ [ 1, 2 ], [ 3, 4, 5 ], [ 6 ] ]) [ [ 1, 3, 6 ], [ 1, 4, 6 ], [ 1, 5, 6 ], [ 2, 3, 6 ], [ 2, 4, 6 ], [ 2, 5, 6 ] ] + , test "computes the cartesian product of a single list" <| + \() -> + Expect.equal (cartesianProduct [ [ 1, 2 ] ]) [ [ 1 ], [ 2 ] ] + , test "computes the cartesian product of lists including an empty one" <| + \() -> + Expect.equal (cartesianProduct [ [ 1, 2 ], [], [ 6 ] ]) [] + , test "computes the nullary cartesian product" <| + \() -> + Expect.equal (cartesianProduct []) [ [] ] + ] + , describe "foldl1" <| + [ test "computes maximum" <| + \() -> + Expect.equal (foldl1 max [ 1, 2, 3, 2, 1 ]) (Just 3) + , test "falls back to Nothing" <| + \() -> + Expect.equal (foldl1 max []) Nothing + , test "computes left to right difference" <| + \() -> + Expect.equal (foldl1 (-) [ 1, 2, 3 ]) (Just -4) + ] + , describe "foldr1" <| + [ test "computes minimum" <| + \() -> + Expect.equal (foldr1 min [ 1, 2, 3, 2, 1 ]) (Just 1) + , test "falls back to Nothing" <| + \() -> + Expect.equal (foldr1 min []) Nothing + , test "computes right to left difference" <| + \() -> + Expect.equal (foldr1 (-) [ 1, 2, 3 ]) (Just 2) + ] + , describe "scanl1" <| + [ test "computes left to right iterative sum" <| + \() -> + Expect.equal (scanl1 (+) [ 1, 2, 3 ]) [ 1, 3, 6 ] + , test "computes left to right iterative difference" <| + \() -> + Expect.equal (scanl1 (-) [ 1, 2, 3 ]) [ 1, 1, 2 ] + , test "computes left to right flipped iterative difference" <| + \() -> + Expect.equal (scanl1 (flip (-)) [ 1, 2, 3 ]) [ 1, -1, -4 ] + ] + , describe "scanr" <| + [ test "computes right to left iterative sum" <| + \() -> + Expect.equal (scanr (+) 0 [ 1, 2, 3 ]) [ 6, 5, 3, 0 ] + , test "computes right to left iterative difference" <| + \() -> + Expect.equal (scanr (-) 0 [ 1, 2, 3 ]) [ 2, -1, 3, 0 ] + ] + , describe "scanr1" <| + [ test "computes right to left iterative sum" <| + \() -> + Expect.equal (scanr1 (+) [ 1, 2, 3 ]) [ 6, 5, 3 ] + , test "computes right to left iterative difference" <| + \() -> + Expect.equal (scanr1 (-) [ 1, 2, 3 ]) [ 2, -1, 3 ] + , test "computes right to left flipped iterative difference" <| + \() -> + Expect.equal (scanr1 (flip (-)) [ 1, 2, 3 ]) [ 0, 1, 3 ] + ] + , describe "mapAccuml" <| + [ test "on empty list" <| + \() -> + Expect.equal + (mapAccuml (\a x -> ( a + x, a * x )) 5 []) + ( 5, [] ) + , test "accumulate sum and map product" <| + \() -> + Expect.equal + (mapAccuml (\a x -> ( a + x, a * x )) 5 [ 2, 4, 8 ]) + ( 19, [ 10, 28, 88 ] ) + , test "running total" <| + \() -> + Expect.equal + (mapAccuml (\a x -> ( a + x, ( x, a + x ) )) 0 [ 2, 4, 8 ]) + ( 14, [ ( 2, 2 ), ( 4, 6 ), ( 8, 14 ) ] ) + , test "works for very long list (i.e. is call stack size safe)" <| + \() -> + Expect.equal + (mapAccuml (\a x -> ( a + x, () )) 0 (List.range 1 100000) |> Tuple.first) + 5000050000 + ] + , describe "mapAccumr" <| + [ test "on empty list" <| + \() -> + Expect.equal + (mapAccumr (\a x -> ( a + x, a * x )) 5 []) + ( 5, [] ) + , test "accumulate sum and map product" <| + \() -> + Expect.equal + (mapAccumr (\a x -> ( a + x, a * x )) 5 [ 2, 4, 8 ]) + ( 19, [ 34, 52, 40 ] ) + , test "add count down" <| + \() -> + Expect.equal + (mapAccumr (\a x -> ( a + 1, ( x, a ) )) 0 [ 2, 4, 8 ]) + ( 3, [ ( 2, 2 ), ( 4, 1 ), ( 8, 0 ) ] ) + , test "works for very long list (i.e. is call stack size safe)" <| + \() -> + Expect.equal + (mapAccumr (\a x -> ( a + x, () )) 0 (List.range 1 100000) |> Tuple.first) + 5000050000 + ] + , describe "unfoldr" <| + [ test "builds a decreasing list from a seed" <| + \() -> + Expect.equal + (unfoldr + (\b -> + if b == 0 then + Nothing + else + Just ( b, b - 1 ) + ) + 5 + ) + [ 5, 4, 3, 2, 1 ] + ] + , describe "iterate" <| + [ test "collatz 13" <| + \() -> + let + collatz n = + if n == 1 then + Nothing + else + Just <| + if n % 2 == 0 then + n / 2 + else + 3 * n + 1 + in + Expect.equal (iterate collatz 13) [ 13, 40, 20, 10, 5, 16, 8, 4, 2, 1 ] + ] + , describe "initialize" <| + [ test "creates a list starting from zero" <| + \() -> + Expect.equal (initialize 5 identity) [ 0, 1, 2, 3, 4 ] + , test "creates a list by doubling the index" <| + \() -> + Expect.equal (initialize 5 (\x -> x * 2)) [ 0, 2, 4, 6, 8 ] + , test "creates a list of identical values" <| + \() -> + Expect.equal (initialize 1 (always 3)) [ 3 ] + ] + , describe "cycle" <| + [ test "same length" <| + \() -> + Expect.equal (cycle 3 [ 4, 7, 8 ]) [ 4, 7, 8 ] + , test "multiple of length" <| + \() -> + Expect.equal (cycle 6 [ 4, 7, 8 ]) [ 4, 7, 8, 4, 7, 8 ] + , test "partial cycle" <| + \() -> + Expect.equal (cycle 4 [ 'a', 'b', 'c' ]) [ 'a', 'b', 'c', 'a' ] + , test "empty list" <| + \() -> + Expect.equal (cycle 9001 []) [] + , test "resulting length smaller than cycle length" <| + \() -> + Expect.equal (cycle 2 [ 1, 2, 3, 4, 5 ]) [ 1, 2 ] + ] + , describe "splitAt" <| + [ test "splits a list in the middle" <| + \() -> + Expect.equal (splitAt 3 [ 1, 2, 3, 4, 5 ]) ( [ 1, 2, 3 ], [ 4, 5 ] ) + , test "splits a list at the first element" <| + \() -> + Expect.equal (splitAt 1 [ 1, 2, 3 ]) ( [ 1 ], [ 2, 3 ] ) + , test "splits the entire list correctly" <| + \() -> + Expect.equal (splitAt 3 [ 1, 2, 3 ]) ( [ 1, 2, 3 ], [] ) + , test "splits past the length of the list" <| + \() -> + Expect.equal (splitAt 4 [ 1, 2, 3 ]) ( [ 1, 2, 3 ], [] ) + , test "handles zero correctly" <| + \() -> + Expect.equal (splitAt 0 [ 1, 2, 3 ]) ( [], [ 1, 2, 3 ] ) + , test "handles negative numbers correctly" <| + \() -> + Expect.equal (splitAt (-1) [ 1, 2, 3 ]) ( [], [ 1, 2, 3 ] ) + ] + , describe "splitWhen" <| + [ test "returns split list when predicate is true" <| + \() -> + Expect.equal (splitWhen (\n -> n == 3) [ 1, 2, 3, 4, 5 ]) (Just ( [ 1, 2 ], [ 3, 4, 5 ] )) + , test "returns nothing when predicate is false" <| + \() -> + Expect.equal (splitWhen (\n -> n == 6) [ 1, 2, 3, 4, 5 ]) Nothing + ] + , describe "takeWhileRight" <| + [ test "keeps the correct items" <| + \() -> + Expect.equal (takeWhileRight ((<) 5) (range 1 10)) [ 6, 7, 8, 9, 10 ] + , test "drops the correct items" <| + \() -> + Expect.equal (dropWhileRight ((<) 5) (range 1 10)) [ 1, 2, 3, 4, 5 ] + ] + , describe "takeWhile" <| + [ test "doesn't exceed maximum call stack" <| + \() -> + Expect.equal (takeWhile ((>) 19999) (range 1 20000)) (range 1 19998) + ] + , describe "span" <| + [ test "splits in the middle of the list" <| + \() -> + Expect.equal (span ((>) 3) [ 1, 2, 3, 4, 1, 2, 3, 4 ]) ( [ 1, 2 ], [ 3, 4, 1, 2, 3, 4 ] ) + , test "every element passes predicate" <| + \() -> + Expect.equal (span ((>) 5) [ 1, 2, 3 ]) ( [ 1, 2, 3 ], [] ) + , test "first item doesn't pass predicate" <| + \() -> + Expect.equal (span ((>) 0) [ 1, 2, 3 ]) ( [], [ 1, 2, 3 ] ) + ] + , describe "break" <| + [ test "breaks in the middle of the list" <| + \() -> + Expect.equal (break ((<) 3) [ 1, 2, 3, 4, 1, 2, 3, 4 ]) ( [ 1, 2, 3 ], [ 4, 1, 2, 3, 4 ] ) + , test "breaks on the first item" <| + \() -> + Expect.equal (break ((>) 5) [ 1, 2, 3 ]) ( [], [ 1, 2, 3 ] ) + , test "doesn't break for any element" <| + \() -> + Expect.equal (break ((<) 5) [ 1, 2, 3 ]) ( [ 1, 2, 3 ], [] ) + ] + , describe "stripPrefix" <| + [ test "removes a matching prefix" <| + \() -> + Expect.equal (stripPrefix [ 1, 2 ] [ 1, 2, 3, 4 ]) (Just [ 3, 4 ]) + , test "removes a matching 3-element prefix" <| + \() -> + Expect.equal (stripPrefix [ 1, 2, 3 ] [ 1, 2, 3, 4, 5 ]) (Just [ 4, 5 ]) + , test "can remove the entire list" <| + \() -> + Expect.equal (stripPrefix [ 1, 2, 3 ] [ 1, 2, 3 ]) (Just []) + , test "fails when prefix is longer than list" <| + \() -> + Expect.equal (stripPrefix [ 1, 2, 3 ] [ 1, 2 ]) Nothing + , test "fails when list doesn't contain prefix" <| + \() -> + Expect.equal (stripPrefix [ 3, 2, 1 ] [ 1, 2, 3, 4, 5 ]) Nothing + ] + , describe "group" <| + [ test "groups elements correctly" <| + \() -> + Expect.equal (group [ 1, 2, 2, 3, 3, 3, 2, 2, 1 ]) [ [ 1 ], [ 2, 2 ], [ 3, 3, 3 ], [ 2, 2 ], [ 1 ] ] + ] + , describe "groupWhile" <| + [ test "groups by sub-element equality" <| + \() -> + Expect.equal + (groupWhile (\x y -> first x == first y) [ ( 0, 'a' ), ( 0, 'b' ), ( 1, 'c' ), ( 1, 'd' ) ]) + [ [ ( 0, 'a' ), ( 0, 'b' ) ], [ ( 1, 'c' ), ( 1, 'd' ) ] ] + , test "comparison function is reflexive, symmetric, and transitive" <| + \() -> + Expect.equal + (groupWhile (<) [ 1, 2, 3, 2, 4, 1, 3, 2, 1 ]) + [ [ 1, 2, 3, 2, 4 ], [ 1, 3, 2 ], [ 1 ] ] + ] + , describe "groupWhileTransitively" <| + [ test "an empty list" <| + \() -> + Expect.equal + (groupWhileTransitively (<) []) + [] + , test "a single item" <| + \() -> + Expect.equal + (groupWhileTransitively (<) [ 1 ]) + [ [ 1 ] ] + , test "a standard working case" <| + \() -> + Expect.equal + (groupWhileTransitively (<) [ 1, 2, 3, 2, 4, 1, 3, 2, 1 ]) + [ [ 1, 2, 3 ], [ 2, 4 ], [ 1, 3 ], [ 2 ], [ 1 ] ] + ] + , describe "inits" <| + [ test "returns all initial segments" <| + \() -> + Expect.equal (inits [ 1, 2, 3 ]) [ [], [ 1 ], [ 1, 2 ], [ 1, 2, 3 ] ] + ] + , describe "tails" <| + [ test "returns all final segments" <| + \() -> + Expect.equal (tails [ 1, 2, 3 ]) [ [ 1, 2, 3 ], [ 2, 3 ], [ 3 ], [] ] + ] + , describe "select" <| + [ test "returns all variations with a single item removed" <| + \() -> + Expect.equal + (select [ 1, 2, 3, 4 ]) + [ ( 1, [ 2, 3, 4 ] ), ( 2, [ 1, 3, 4 ] ), ( 3, [ 1, 2, 4 ] ), ( 4, [ 1, 2, 3 ] ) ] + ] + , describe "selectSplit" <| + [ test "returns all splits at a single item" <| + \() -> + Expect.equal (selectSplit [ 1, 2, 3 ]) [ ( [], 1, [ 2, 3 ] ), ( [ 1 ], 2, [ 3 ] ), ( [ 1, 2 ], 3, [] ) ] + ] + , describe "isSubsequenceOf" <| + [ test "success" <| + \() -> + Expect.true "Elm is a subsequence of Eat lime" (isSubsequenceOf [ "E", "l", "m" ] [ "E", "a", "t", " ", "l", "i", "m", "e", "s" ]) + , test "failure" <| + \() -> + Expect.false "Elm is not a subsequence of Email" (isSubsequenceOf [ "E", "l", "m" ] [ "E", "m", "a", "i", "l" ]) + , test "success at last element" <| + \() -> + Expect.true "[] should be a subsequence of []" (isSubsequenceOf [ 1, 3 ] [ 1, 2, 3 ]) + ] + , describe "lift2" <| + [ test "produces all combinations of addition" <| + \() -> + Expect.equal (lift2 (+) [ 1, 2, 3 ] [ 4, 5 ]) [ 5, 6, 6, 7, 7, 8 ] + ] + , describe "groupsOf" <| + [ test "groups by the correct number of items" <| + \() -> + Expect.equal (groupsOf 3 (range 1 10)) + [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] + ] + , describe "groupsOfWithStep" <| + [ test "step == size" <| + \() -> + Expect.equal (groupsOfWithStep 4 4 (range 1 10)) + [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ] ] + , test "step < size" <| + \() -> + Expect.equal (groupsOfWithStep 3 1 (range 1 5)) + [ [ 1, 2, 3 ], [ 2, 3, 4 ], [ 3, 4, 5 ] ] + , test "step > size" <| + \() -> + Expect.equal (groupsOfWithStep 3 6 (range 1 20)) + [ [ 1, 2, 3 ], [ 7, 8, 9 ], [ 13, 14, 15 ] ] + ] + , describe "groupsOfVarying" <| + [ test "group sizes match passed sizes" <| + \() -> + Expect.equal + (groupsOfVarying [ 2, 3, 1 ] [ "a", "b", "c", "d", "e", "f" ]) + [ [ "a", "b" ], [ "c", "d", "e" ], [ "f" ] ] + , test "groups correctly when passed counts are less than list size" <| + \() -> + Expect.equal + (groupsOfVarying [ 2 ] [ "a", "b", "c", "d", "e", "f" ]) + [ [ "a", "b" ] ] + , test "groups correctly when passed counts are greater than list size" <| + \() -> + Expect.equal + (groupsOfVarying [ 2, 3, 1, 5, 6 ] [ "a", "b", "c", "d", "e" ]) + [ [ "a", "b" ], [ "c", "d", "e" ] ] + ] + , describe "greedyGroupsOf" <| + [ test "groups correctly while keeping trailing group" <| + \() -> + Expect.equal (greedyGroupsOf 3 (range 1 10)) + [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ], [ 10 ] ] + ] + , describe "greedyGroupsOfWithStep" <| + [ test "step == size" <| + \() -> + Expect.equal (greedyGroupsOfWithStep 4 4 (range 1 10)) + [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10 ] ] + , test "step < size" <| + \() -> + Expect.equal (greedyGroupsOfWithStep 3 2 (range 1 6)) + [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 5, 6 ] ] + , test "step > size" <| + \() -> + Expect.equal (greedyGroupsOfWithStep 3 6 (range 1 20)) + [ [ 1, 2, 3 ], [ 7, 8, 9 ], [ 13, 14, 15 ], [ 19, 20 ] ] + ] + , describe "isPrefixOf" + [ fuzz (list int) "[] is prefix to anything" <| + \list -> + List.Extra.isPrefixOf [] list + |> Expect.true "Expected [] to be a prefix." + , fuzz (list int) "reflexivity" <| + \list -> + List.Extra.isPrefixOf list list + |> Expect.true "Expected list to be a prefix of itself." + , fuzz2 (list int) (list int) "antisymmetry" <| + \listA listB -> + not (List.Extra.isPrefixOf listA listB) + || not (List.Extra.isPrefixOf listB listA) + || listA + == listB + |> Expect.true "Expected exactly one to be prefix of the other." + , fuzz3 (list int) (list int) (list int) "transitivity" <| + \listA listB listC -> + not (List.Extra.isPrefixOf listA listB) + || not (List.Extra.isPrefixOf listB listC) + || List.Extra.isPrefixOf listA listC + |> Expect.true "Expected prefix of prefix to be prefix." + ] + , describe "isSuffixOf" + [ fuzz (list int) "[] is suffix to anything" <| + \list -> + List.Extra.isSuffixOf [] list + |> Expect.true "Expected [] to be a suffix." + , fuzz (list int) "reflexivity" <| + \list -> + List.Extra.isSuffixOf list list + |> Expect.true "Expected list to be a suffix of itself." + , fuzz2 (list int) (list int) "antisymmetry" <| + \listA listB -> + not (List.Extra.isSuffixOf listA listB) + || not (List.Extra.isSuffixOf listB listA) + || listA + == listB + |> Expect.true "Expected exactly one to be suffix of the other." + , fuzz3 (list int) (list int) (list int) "transitivity" <| + \listA listB listC -> + not (List.Extra.isSuffixOf listA listB) + || not (List.Extra.isSuffixOf listB listC) + || List.Extra.isSuffixOf listA listC + |> Expect.true "Expected suffix of suffix to be suffix." + ] + , describe "isInfixOf" + [ test "success" <| + \() -> + Expect.true "5, 7, 11 is infix of 2, 3, 5, 7, 11, 13" (isInfixOf [ 5, 7, 11 ] [ 2, 3, 5, 7, 11, 13 ]) + , test "not consecutive" <| + \() -> + Expect.false "5, 7, 13 is not infix of 2, 3, 5, 7, 11, 13" (isInfixOf [ 5, 7, 13 ] [ 2, 3, 5, 7, 11, 13 ]) + , test "not in-order" <| + \() -> + Expect.false "3, 5, 2 is not infix of 2, 3, 5, 7, 11, 13" (isInfixOf [ 3, 5, 2 ] [ 2, 3, 5, 7, 11, 13 ]) + ] + , describe "swapAt" + [ test "negative index as first argument returns the original list" <| + \() -> + Expect.equal (swapAt -1 0 [ 1, 2, 3 ]) [ 1, 2, 3 ] + , test "negative index as second argument returns the original list" <| + \() -> + Expect.equal (swapAt 0 -1 [ 1, 2, 3 ]) [ 1, 2, 3 ] + , test "out of range index as first argument returns the original list" <| + \() -> + Expect.equal (swapAt 10 0 [ 1, 2, 3 ]) [ 1, 2, 3 ] + , test "out of range index as second argument returns the original list" <| + \() -> + Expect.equal (swapAt 0 -1 [ 1, 2, 3 ]) [ 1, 2, 3 ] + , test "identical indexes returns the original list" <| + \() -> + Expect.equal (swapAt 1 1 [ 1, 2, 3 ]) [ 1, 2, 3 ] + , test "swap the elements at indices 0 and 1" <| + \() -> + Expect.equal (swapAt 0 1 [ 1, 2, 3 ]) [ 2, 1, 3 ] + ] + , describe "removeAt" + [ test "negative index returns the original list" <| + \() -> + Expect.equal (removeAt -1 [ 1, 2, 3 ]) [ 1, 2, 3 ] + , test "remove the element at index 0" <| + \() -> + Expect.equal (removeAt 0 [ 1, 2, 3 ]) [ 2, 3 ] + , test "remove the element at index 2" <| + \() -> + Expect.equal (removeAt 2 [ 1, 2, 3 ]) [ 1, 2 ] + , test "out of range index returns the original list" <| + \() -> + Expect.equal (removeAt 4 [ 1, 2, 3 ]) [ 1, 2, 3 ] + ] + , describe "setAt" + [ test "negative index returns the original list" <| + \() -> + Expect.equal (setAt -1 9 [ 1, 2, 3 ]) [ 1, 2, 3 ] + , test "set index 0 to 9" <| + \() -> + Expect.equal (setAt 0 9 [ 1, 2, 3 ]) [ 9, 2, 3 ] + , test "set index 2 to 9" <| + \() -> + Expect.equal (setAt 2 9 [ 1, 2, 3 ]) [ 1, 2, 9 ] + , test "out of range index returns the original list" <| + \() -> + Expect.equal (setAt 4 9 [ 1, 2, 3 ]) [ 1, 2, 3 ] + ] + , describe "updateAt" + [ test "negative index returns the original list" <| + \() -> + Expect.equal (updateAt -1 ((+) 1) [ 1, 2, 3 ]) [ 1, 2, 3 ] + , test "increment the element at index 0" <| + \() -> + Expect.equal (updateAt 0 ((+) 1) [ 1, 2, 3 ]) [ 2, 2, 3 ] + , test "increment the element at index 2" <| + \() -> + Expect.equal (updateAt 2 ((+) 1) [ 1, 2, 3 ]) [ 1, 2, 4 ] + , test "out of range index returns the original list" <| + \() -> + Expect.equal (updateAt 4 ((+) 1) [ 1, 2, 3 ]) [ 1, 2, 3 ] + ] + , describe "updateIfIndex" + [ test "increments first element" <| + \() -> + Expect.equal (updateIfIndex (always True) ((+) 1) [ 1, 2, 3 ]) [ 2, 3, 4 ] + , test "if the index is 2, then increment the element" <| + \() -> + Expect.equal (updateIfIndex ((==) 2) ((+) 1) [ 1, 2, 3 ]) [ 1, 2, 4 ] + , test "if the index is even, increment the element" <| + \() -> + Expect.equal (updateIfIndex (\index -> index % 2 == 0) ((+) 1) [ 1, 2, 3 ]) [ 2, 2, 4 ] + ] + , describe "removeIfIndex" + [ test "remove all the elements" <| + \() -> + Expect.equal (removeIfIndex (always True) [ 1, 2, 3 ]) [] + , test "remove the element at index 2" <| + \() -> + Expect.equal (removeIfIndex ((==) 2) [ 1, 2, 3 ]) [ 1, 2 ] + , test "remove all elements at even indices" <| + \() -> + Expect.equal (removeIfIndex (\index -> index % 2 == 0) [ 1, 2, 3 ]) [ 2 ] + ] + ] diff --git a/client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/elm-package.json b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/elm-package.json new file mode 100644 index 0000000..91b29cc --- /dev/null +++ b/client/elm-stuff/packages/elm-community/list-extra/7.1.0/tests/elm-package.json @@ -0,0 +1,19 @@ +{ + "version": "1.0.0", + "summary": "List.Extra Test Suite", + "repository": "https://github.com/elm-community/list-extra.git", + "license": "MIT", + "source-directories": [ + ".", + "../src" + ], + "exposed-modules": [], + "dependencies": { + "elm-community/json-extra": "2.0.0 <= v < 3.0.0", + "elm-lang/html": "2.0.0 <= v < 3.0.0", + "mgold/elm-random-pcg": "4.0.2 <= v < 5.0.0", + "elm-lang/core": "5.0.0 <= v < 6.0.0", + "elm-community/elm-test": "4.0.0 <= v < 5.0.0" + }, + "elm-version": "0.18.0 <= v < 0.19.0" +} diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/.gitignore b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/.gitignore new file mode 100644 index 0000000..4bc8535 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/.gitignore @@ -0,0 +1 @@ +elm-stuff diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/README.md b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/README.md new file mode 100644 index 0000000..e58b71d --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/README.md @@ -0,0 +1,13 @@ +# elm-community/random-extra +This library includes lots of extra helper functions for the Random module. It makes generating pseudo-random values much easier. + +If you want to add one or find a bug, please [open an issue](https://github.com/elm-community/random-extra/issues/new). + +## Changelog +### 2.0.0 +* Update dependencies for Elm 0.18. +* Remove `flatMap` as core's `andThen` is identical. +* Rename `flatMapN` to `andThenN`, for similar reasons. +* Rename `together` to `combine`; see #1. +* Change signature of `Random.Extra.Float.normal`; see #2. +* Add `Random.Extra.List` module; see #4. diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/elm-package.json b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/elm-package.json new file mode 100644 index 0000000..ffcb6dc --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/elm-package.json @@ -0,0 +1,27 @@ +{ + "version": "2.0.0", + "summary": "Extra functions for the core Random library", + "repository": "https://github.com/elm-community/random-extra.git", + "license": "MIT", + "source-directories": [ + "src" + ], + "exposed-modules": [ + "Random.Array", + "Random.Char", + "Random.Color", + "Random.Date", + "Random.Dict", + "Random.Extra", + "Random.Float", + "Random.Int", + "Random.List", + "Random.Order", + "Random.Set", + "Random.String" + ], + "dependencies": { + "elm-lang/core": "5.0.0 <= v < 6.0.0" + }, + "elm-version": "0.18.0 <= v < 0.19.0" +} diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Array.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Array.elm new file mode 100644 index 0000000..1ee6c35 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Array.elm @@ -0,0 +1,104 @@ +module Random.Array exposing (..) + +{-| Extra randomized functions on arrays. + +# Create an Array +@docs array, rangeLengthArray + +# Work with an Array +@docs sample, choose, shuffle + +-} + +import Array exposing (Array, fromList, empty) +import Random exposing (Generator, map, list, int, andThen) +import Random.Extra exposing (constant) + + +{-| Generate a random array of given size given a random generator + + randomLength5IntArray = array 5 (int 0 100) +-} +array : Int -> Generator a -> Generator (Array a) +array arrayLength generator = + map fromList (list arrayLength generator) + + +{-| Generate a random array of random length given a minimum length and +a maximum length. +-} +rangeLengthArray : Int -> Int -> Generator a -> Generator (Array a) +rangeLengthArray minLength maxLength generator = + andThen (\len -> array len generator) (int minLength maxLength) + + +{-| Sample with replacement: produce a randomly selected element of the +array, or `Nothing` for an empty array. Takes O(1) time. +-} +sample : Array a -> Generator (Maybe a) +sample arr = + let + gen = + Random.int 0 (Array.length arr - 1) + in + Random.map (\index -> Array.get index arr) gen + + +{-| Sample without replacement: produce a randomly selected element of the +array, and the array with that element omitted (shifting all later elements +down). If the array is empty, the selected element will be `Nothing`. +-} +choose : Array a -> Generator ( Maybe a, Array a ) +choose arr = + if Array.isEmpty arr then + constant ( Nothing, arr ) + else + let + lastIndex = + Array.length arr - 1 + + front i = + Array.slice 0 i arr + + back i = + if + i == lastIndex + -- workaround for #1 + then + Array.empty + else + Array.slice (i + 1) (lastIndex + 1) arr + + gen = + Random.int 0 lastIndex + in + Random.map + (\index -> + ( Array.get index arr, Array.append (front index) (back index) ) + ) + gen + + +{-| Shuffle the array using the Fisher-Yates algorithm. Takes O(_n_ log _n_) +time and O(_n_) additional space. +-} +shuffle : Array a -> Generator (Array a) +shuffle arr = + if Array.isEmpty arr then + constant arr + else + let + helper : ( List a, Array a ) -> Generator ( List a, Array a ) + helper ( done, remaining ) = + choose remaining + |> andThen + (\( m_val, shorter ) -> + case m_val of + Nothing -> + constant ( done, shorter ) + + Just val -> + helper ( val :: done, shorter ) + ) + in + Random.map (Tuple.first >> Array.fromList) (helper ( [], arr )) diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Char.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Char.elm new file mode 100644 index 0000000..8ecec00 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Char.elm @@ -0,0 +1,1390 @@ +module Random.Char exposing (..) + +{-| Extra randomized functions on characters. + +# Basic Generators +@docs char, lowerCaseLatin, upperCaseLatin, latin, english, ascii, unicode + +# Unicode Generators (UTF-8) +@docs basicLatin, latin1Supplement, latinExtendedA, latinExtendedB, ipaExtensions, spacingModifier, combiningDiacriticalMarks, greekAndCoptic, cyrillic, cyrillicSupplement, armenian, hebrew, arabic, syriac, arabicSupplement, thaana, nko, samaritan, mandaic, arabicExtendedA, devanagari, bengali, gurmukhi, gujarati, oriya, tamil, telugu, kannada, malayalam, sinhala, thai, lao, tibetan, myanmar, georgian, hangulJamo, ethiopic, ethiopicSupplement, cherokee, unifiedCanadianAboriginalSyllabic, ogham, runic, tagalog, hanunoo, buhid, tagbanwa, khmer, mongolian, unifiedCanadianAboriginalSyllabicExtended, limbu, taiLe, newTaiLue, khmerSymbol, buginese, taiTham, balinese, sundanese, batak, lepcha, olChiki, sundaneseSupplement, vedicExtensions, phoneticExtensions, phoneticExtensionsSupplement, combiningDiacriticalMarksSupplement, latinExtendedAdditional, greekExtended, generalPunctuation, superscriptOrSubscript, currencySymbol, combiningDiacriticalMarksForSymbols, letterlikeSymbol, numberForm, arrow, mathematicalOperator, miscellaneousTechnical, controlPicture, opticalCharacterRecognition, enclosedAlphanumeric, boxDrawing, blockElement, geometricShape, miscellaneousSymbol, dingbat, miscellaneousMathematicalSymbolA, supplementalArrowA, braillePattern, supplementalArrowB, miscellaneousMathematicalSymbolB, supplementalMathematicalOperator, miscellaneousSymbolOrArrow, glagolitic, latinExtendedC, coptic, georgianSupplement, tifinagh, ethiopicExtended, cyrillicExtendedA, supplementalPunctuation, cjkRadicalSupplement, kangxiRadical, ideographicDescription, cjkSymbolOrPunctuation, hiragana, katakana, bopomofo, hangulCompatibilityJamo, kanbun, bopomofoExtended, cjkStroke, katakanaPhoneticExtension, enclosedCJKLetterOrMonth, cjkCompatibility, cjkUnifiedIdeographExtensionA, yijingHexagramSymbol, cjkUnifiedIdeograph, yiSyllable, yiRadical, lisu, vai, cyrillicExtendedB, bamum, modifierToneLetter, latinExtendedD, sylotiNagri, commonIndicNumberForm, phagsPa, saurashtra, devanagariExtended, kayahLi, rejang, hangulJamoExtendedA, javanese, cham, myanmarExtendedA, taiViet, meeteiMayekExtension, ethiopicExtendedA, meeteiMayek, hangulSyllable, hangulJamoExtendedB, highSurrogate, highPrivateUseSurrogate, lowSurrogate, privateUseArea, cjkCompatibilityIdeograph, alphabeticPresentationForm, arabicPresentationFormA, variationSelector, verticalForm, combiningHalfMark, cjkCompatibilityForm, smallFormVariant, arabicPresentationFormB, halfwidthOrFullwidthForm, special, linearBSyllable, linearBIdeogram, aegeanNumber, ancientGreekNumber, ancientSymbol, phaistosDisc, lycian, carian, oldItalic, gothic, ugaritic, oldPersian, deseret, shavian, osmanya, cypriotSyllable, imperialAramaic, phoenician, lydian, meroiticHieroglyph, meroiticCursive, kharoshthi, oldSouthArabian, avestan, inscriptionalParthian, inscriptionalPahlavi, oldTurkic, rumiNumericalSymbol, brahmi, kaithi, soraSompeng, chakma, sharada, takri, cuneiform, cuneiformNumberOrPunctuation, egyptianHieroglyph, bamumSupplement, miao, kanaSupplement, byzantineMusicalSymbol, musicalSymbol, ancientGreekMusicalNotationSymbol, taiXuanJingSymbol, countingRodNumeral, mathematicalAlphanumericSymbol, arabicMathematicalAlphabeticSymbol, mahjongTile, dominoTile, playingCard, enclosedAlphanumericSupplement, enclosedIdeographicSupplement, miscellaneousSymbolOrPictograph, emoticon, transportOrMapSymbol, alchemicalSymbol, cjkUnifiedIdeographExtensionB, cjkUnifiedIdeographExtensionC, cjkUnifiedIdeographExtensionD, cjkCompatibilityIdeographSupplement, tag, variationSelectorSupplement, supplementaryPrivateUseAreaA, supplementaryPrivateUseAreaB + +-} + +import Char exposing (fromCode) +import Random exposing (Generator, map, int) +import Random.Extra exposing (choices) + + +{-| Generate a random character within a certain keyCode range + + lowerCaseLetter = char 65 90 +-} +char : Int -> Int -> Generator Char +char start end = + map fromCode (int start end) + + +{-| Generate a random upper-case Latin Letter +-} +upperCaseLatin : Generator Char +upperCaseLatin = + char 65 90 + + +{-| Generate a random lower-case Latin Letter +-} +lowerCaseLatin : Generator Char +lowerCaseLatin = + char 97 122 + + +{-| Generate a random Latin Letter +-} +latin : Generator Char +latin = + choices [ lowerCaseLatin, upperCaseLatin ] + + +{-| Generate a random English Letter (alias for `latin`) +-} +english : Generator Char +english = + latin + + +{-| Generate a random ASCII Character +-} +ascii : Generator Char +ascii = + char 0 127 + + +{-| Generate a random Character in the valid unicode range. +Note: This can produce garbage values as unicode doesn't use all valid values. +To test for specific languages and character sets, use the appropriate one +from the list. +-} +unicode : Generator Char +unicode = + char 0 1114111 + + +{-| UTF-8 +-} +basicLatin : Generator Char +basicLatin = + char 0 127 + + +{-| -} +latin1Supplement : Generator Char +latin1Supplement = + char 128 255 + + +{-| -} +latinExtendedA : Generator Char +latinExtendedA = + char 256 383 + + +{-| -} +latinExtendedB : Generator Char +latinExtendedB = + char 384 591 + + +{-| -} +ipaExtensions : Generator Char +ipaExtensions = + char 592 687 + + +{-| -} +spacingModifier : Generator Char +spacingModifier = + char 688 767 + + +{-| -} +combiningDiacriticalMarks : Generator Char +combiningDiacriticalMarks = + char 768 879 + + +{-| -} +greekAndCoptic : Generator Char +greekAndCoptic = + char 880 1023 + + +{-| -} +cyrillic : Generator Char +cyrillic = + char 1024 1279 + + +{-| -} +cyrillicSupplement : Generator Char +cyrillicSupplement = + char 1280 1327 + + +{-| -} +armenian : Generator Char +armenian = + char 1328 1423 + + +{-| -} +hebrew : Generator Char +hebrew = + char 1424 1535 + + +{-| -} +arabic : Generator Char +arabic = + char 1536 1791 + + +{-| -} +syriac : Generator Char +syriac = + char 1792 1871 + + +{-| -} +arabicSupplement : Generator Char +arabicSupplement = + char 1872 1919 + + +{-| -} +thaana : Generator Char +thaana = + char 1920 1983 + + +{-| -} +nko : Generator Char +nko = + char 1984 2047 + + +{-| -} +samaritan : Generator Char +samaritan = + char 2048 2111 + + +{-| -} +mandaic : Generator Char +mandaic = + char 2112 2143 + + +{-| -} +arabicExtendedA : Generator Char +arabicExtendedA = + char 2208 2303 + + +{-| -} +devanagari : Generator Char +devanagari = + char 2304 2431 + + +{-| -} +bengali : Generator Char +bengali = + char 2432 2559 + + +{-| -} +gurmukhi : Generator Char +gurmukhi = + char 2560 2687 + + +{-| -} +gujarati : Generator Char +gujarati = + char 2688 2815 + + +{-| -} +oriya : Generator Char +oriya = + char 2816 2943 + + +{-| -} +tamil : Generator Char +tamil = + char 2944 3071 + + +{-| -} +telugu : Generator Char +telugu = + char 3072 3199 + + +{-| -} +kannada : Generator Char +kannada = + char 3200 3327 + + +{-| -} +malayalam : Generator Char +malayalam = + char 3328 3455 + + +{-| -} +sinhala : Generator Char +sinhala = + char 3456 3583 + + +{-| -} +thai : Generator Char +thai = + char 3584 3711 + + +{-| -} +lao : Generator Char +lao = + char 3712 3839 + + +{-| -} +tibetan : Generator Char +tibetan = + char 3840 4095 + + +{-| -} +myanmar : Generator Char +myanmar = + char 4096 4255 + + +{-| -} +georgian : Generator Char +georgian = + char 4256 4351 + + +{-| -} +hangulJamo : Generator Char +hangulJamo = + char 4352 4607 + + +{-| -} +ethiopic : Generator Char +ethiopic = + char 4608 4991 + + +{-| -} +ethiopicSupplement : Generator Char +ethiopicSupplement = + char 4992 5023 + + +{-| -} +cherokee : Generator Char +cherokee = + char 5024 5119 + + +{-| -} +unifiedCanadianAboriginalSyllabic : Generator Char +unifiedCanadianAboriginalSyllabic = + char 5120 5759 + + +{-| -} +ogham : Generator Char +ogham = + char 5760 5791 + + +{-| -} +runic : Generator Char +runic = + char 5792 5887 + + +{-| -} +tagalog : Generator Char +tagalog = + char 5888 5919 + + +{-| -} +hanunoo : Generator Char +hanunoo = + char 5920 5951 + + +{-| -} +buhid : Generator Char +buhid = + char 5952 5983 + + +{-| -} +tagbanwa : Generator Char +tagbanwa = + char 5984 6015 + + +{-| -} +khmer : Generator Char +khmer = + char 6016 6143 + + +{-| -} +mongolian : Generator Char +mongolian = + char 6144 6319 + + +{-| -} +unifiedCanadianAboriginalSyllabicExtended : Generator Char +unifiedCanadianAboriginalSyllabicExtended = + char 6320 6399 + + +{-| -} +limbu : Generator Char +limbu = + char 6400 6479 + + +{-| -} +taiLe : Generator Char +taiLe = + char 6480 6527 + + +{-| -} +newTaiLue : Generator Char +newTaiLue = + char 6528 6623 + + +{-| -} +khmerSymbol : Generator Char +khmerSymbol = + char 6624 6655 + + +{-| -} +buginese : Generator Char +buginese = + char 6656 6687 + + +{-| -} +taiTham : Generator Char +taiTham = + char 6688 6831 + + +{-| -} +balinese : Generator Char +balinese = + char 6912 7039 + + +{-| -} +sundanese : Generator Char +sundanese = + char 7040 7103 + + +{-| -} +batak : Generator Char +batak = + char 7104 7167 + + +{-| -} +lepcha : Generator Char +lepcha = + char 7168 7247 + + +{-| -} +olChiki : Generator Char +olChiki = + char 7248 7295 + + +{-| -} +sundaneseSupplement : Generator Char +sundaneseSupplement = + char 7360 7375 + + +{-| -} +vedicExtensions : Generator Char +vedicExtensions = + char 7376 7423 + + +{-| -} +phoneticExtensions : Generator Char +phoneticExtensions = + char 7424 7551 + + +{-| -} +phoneticExtensionsSupplement : Generator Char +phoneticExtensionsSupplement = + char 7552 7615 + + +{-| -} +combiningDiacriticalMarksSupplement : Generator Char +combiningDiacriticalMarksSupplement = + char 7616 7679 + + +{-| -} +latinExtendedAdditional : Generator Char +latinExtendedAdditional = + char 7680 7935 + + +{-| -} +greekExtended : Generator Char +greekExtended = + char 7936 8191 + + +{-| -} +generalPunctuation : Generator Char +generalPunctuation = + char 8192 8303 + + +{-| -} +superscriptOrSubscript : Generator Char +superscriptOrSubscript = + char 8304 8351 + + +{-| -} +currencySymbol : Generator Char +currencySymbol = + char 8352 8399 + + +{-| -} +combiningDiacriticalMarksForSymbols : Generator Char +combiningDiacriticalMarksForSymbols = + char 8400 8447 + + +{-| -} +letterlikeSymbol : Generator Char +letterlikeSymbol = + char 8448 8527 + + +{-| -} +numberForm : Generator Char +numberForm = + char 8528 8591 + + +{-| -} +arrow : Generator Char +arrow = + char 8592 8703 + + +{-| -} +mathematicalOperator : Generator Char +mathematicalOperator = + char 8704 8959 + + +{-| -} +miscellaneousTechnical : Generator Char +miscellaneousTechnical = + char 8960 9215 + + +{-| -} +controlPicture : Generator Char +controlPicture = + char 9216 9279 + + +{-| -} +opticalCharacterRecognition : Generator Char +opticalCharacterRecognition = + char 9280 9311 + + +{-| -} +enclosedAlphanumeric : Generator Char +enclosedAlphanumeric = + char 9312 9471 + + +{-| -} +boxDrawing : Generator Char +boxDrawing = + char 9472 9599 + + +{-| -} +blockElement : Generator Char +blockElement = + char 9600 9631 + + +{-| -} +geometricShape : Generator Char +geometricShape = + char 9632 9727 + + +{-| -} +miscellaneousSymbol : Generator Char +miscellaneousSymbol = + char 9728 9983 + + +{-| -} +dingbat : Generator Char +dingbat = + char 9984 10175 + + +{-| -} +miscellaneousMathematicalSymbolA : Generator Char +miscellaneousMathematicalSymbolA = + char 10176 10223 + + +{-| -} +supplementalArrowA : Generator Char +supplementalArrowA = + char 10224 10239 + + +{-| -} +braillePattern : Generator Char +braillePattern = + char 10240 10495 + + +{-| -} +supplementalArrowB : Generator Char +supplementalArrowB = + char 10496 10623 + + +{-| -} +miscellaneousMathematicalSymbolB : Generator Char +miscellaneousMathematicalSymbolB = + char 10624 10751 + + +{-| -} +supplementalMathematicalOperator : Generator Char +supplementalMathematicalOperator = + char 10752 11007 + + +{-| -} +miscellaneousSymbolOrArrow : Generator Char +miscellaneousSymbolOrArrow = + char 11008 11263 + + +{-| -} +glagolitic : Generator Char +glagolitic = + char 11264 11359 + + +{-| -} +latinExtendedC : Generator Char +latinExtendedC = + char 11360 11391 + + +{-| -} +coptic : Generator Char +coptic = + char 11392 11519 + + +{-| -} +georgianSupplement : Generator Char +georgianSupplement = + char 11520 11567 + + +{-| -} +tifinagh : Generator Char +tifinagh = + char 11568 11647 + + +{-| -} +ethiopicExtended : Generator Char +ethiopicExtended = + char 11648 11743 + + +{-| -} +cyrillicExtendedA : Generator Char +cyrillicExtendedA = + char 11744 11775 + + +{-| -} +supplementalPunctuation : Generator Char +supplementalPunctuation = + char 11776 11903 + + +{-| -} +cjkRadicalSupplement : Generator Char +cjkRadicalSupplement = + char 11904 12031 + + +{-| -} +kangxiRadical : Generator Char +kangxiRadical = + char 12032 12255 + + +{-| -} +ideographicDescription : Generator Char +ideographicDescription = + char 12272 12287 + + +{-| -} +cjkSymbolOrPunctuation : Generator Char +cjkSymbolOrPunctuation = + char 12288 12351 + + +{-| -} +hiragana : Generator Char +hiragana = + char 12352 12447 + + +{-| -} +katakana : Generator Char +katakana = + char 12448 12543 + + +{-| -} +bopomofo : Generator Char +bopomofo = + char 12544 12591 + + +{-| -} +hangulCompatibilityJamo : Generator Char +hangulCompatibilityJamo = + char 12592 12687 + + +{-| -} +kanbun : Generator Char +kanbun = + char 12688 12703 + + +{-| -} +bopomofoExtended : Generator Char +bopomofoExtended = + char 12704 12735 + + +{-| -} +cjkStroke : Generator Char +cjkStroke = + char 12736 12783 + + +{-| -} +katakanaPhoneticExtension : Generator Char +katakanaPhoneticExtension = + char 12784 12799 + + +{-| -} +enclosedCJKLetterOrMonth : Generator Char +enclosedCJKLetterOrMonth = + char 12800 13055 + + +{-| -} +cjkCompatibility : Generator Char +cjkCompatibility = + char 13056 13311 + + +{-| -} +cjkUnifiedIdeographExtensionA : Generator Char +cjkUnifiedIdeographExtensionA = + char 13312 19903 + + +{-| -} +yijingHexagramSymbol : Generator Char +yijingHexagramSymbol = + char 19904 19967 + + +{-| -} +cjkUnifiedIdeograph : Generator Char +cjkUnifiedIdeograph = + char 19968 40959 + + +{-| -} +yiSyllable : Generator Char +yiSyllable = + char 40960 42127 + + +{-| -} +yiRadical : Generator Char +yiRadical = + char 42128 42191 + + +{-| -} +lisu : Generator Char +lisu = + char 42192 42239 + + +{-| -} +vai : Generator Char +vai = + char 42240 42559 + + +{-| -} +cyrillicExtendedB : Generator Char +cyrillicExtendedB = + char 42560 42655 + + +{-| -} +bamum : Generator Char +bamum = + char 42656 42751 + + +{-| -} +modifierToneLetter : Generator Char +modifierToneLetter = + char 42752 42783 + + +{-| -} +latinExtendedD : Generator Char +latinExtendedD = + char 42784 43007 + + +{-| -} +sylotiNagri : Generator Char +sylotiNagri = + char 43008 43055 + + +{-| -} +commonIndicNumberForm : Generator Char +commonIndicNumberForm = + char 43056 43071 + + +{-| -} +phagsPa : Generator Char +phagsPa = + char 43072 43135 + + +{-| -} +saurashtra : Generator Char +saurashtra = + char 43136 43231 + + +{-| -} +devanagariExtended : Generator Char +devanagariExtended = + char 43232 43263 + + +{-| -} +kayahLi : Generator Char +kayahLi = + char 43264 43311 + + +{-| -} +rejang : Generator Char +rejang = + char 43312 43359 + + +{-| -} +hangulJamoExtendedA : Generator Char +hangulJamoExtendedA = + char 43360 43391 + + +{-| -} +javanese : Generator Char +javanese = + char 43392 43487 + + +{-| -} +cham : Generator Char +cham = + char 43520 43615 + + +{-| -} +myanmarExtendedA : Generator Char +myanmarExtendedA = + char 43616 43647 + + +{-| -} +taiViet : Generator Char +taiViet = + char 43648 43743 + + +{-| -} +meeteiMayekExtension : Generator Char +meeteiMayekExtension = + char 43744 43775 + + +{-| -} +ethiopicExtendedA : Generator Char +ethiopicExtendedA = + char 43776 43823 + + +{-| -} +meeteiMayek : Generator Char +meeteiMayek = + char 43968 44031 + + +{-| -} +hangulSyllable : Generator Char +hangulSyllable = + char 44032 55215 + + +{-| -} +hangulJamoExtendedB : Generator Char +hangulJamoExtendedB = + char 55216 55295 + + +{-| -} +highSurrogate : Generator Char +highSurrogate = + char 55296 56191 + + +{-| -} +highPrivateUseSurrogate : Generator Char +highPrivateUseSurrogate = + char 56192 56319 + + +{-| -} +lowSurrogate : Generator Char +lowSurrogate = + char 56320 57343 + + +{-| -} +privateUseArea : Generator Char +privateUseArea = + char 57344 63743 + + +{-| -} +cjkCompatibilityIdeograph : Generator Char +cjkCompatibilityIdeograph = + char 63744 64255 + + +{-| -} +alphabeticPresentationForm : Generator Char +alphabeticPresentationForm = + char 64256 64335 + + +{-| -} +arabicPresentationFormA : Generator Char +arabicPresentationFormA = + char 64336 65023 + + +{-| -} +variationSelector : Generator Char +variationSelector = + char 65024 65039 + + +{-| -} +verticalForm : Generator Char +verticalForm = + char 65040 65055 + + +{-| -} +combiningHalfMark : Generator Char +combiningHalfMark = + char 65056 65071 + + +{-| -} +cjkCompatibilityForm : Generator Char +cjkCompatibilityForm = + char 65072 65103 + + +{-| -} +smallFormVariant : Generator Char +smallFormVariant = + char 65104 65135 + + +{-| -} +arabicPresentationFormB : Generator Char +arabicPresentationFormB = + char 65136 65279 + + +{-| -} +halfwidthOrFullwidthForm : Generator Char +halfwidthOrFullwidthForm = + char 65280 65519 + + +{-| -} +special : Generator Char +special = + char 65520 65535 + + +{-| -} +linearBSyllable : Generator Char +linearBSyllable = + char 65536 65663 + + +{-| -} +linearBIdeogram : Generator Char +linearBIdeogram = + char 65664 65791 + + +{-| -} +aegeanNumber : Generator Char +aegeanNumber = + char 65792 65855 + + +{-| -} +ancientGreekNumber : Generator Char +ancientGreekNumber = + char 65856 65935 + + +{-| -} +ancientSymbol : Generator Char +ancientSymbol = + char 65936 65999 + + +{-| -} +phaistosDisc : Generator Char +phaistosDisc = + char 66000 66047 + + +{-| -} +lycian : Generator Char +lycian = + char 66176 66207 + + +{-| -} +carian : Generator Char +carian = + char 66208 66271 + + +{-| -} +oldItalic : Generator Char +oldItalic = + char 66304 66351 + + +{-| -} +gothic : Generator Char +gothic = + char 66352 66383 + + +{-| -} +ugaritic : Generator Char +ugaritic = + char 66432 66463 + + +{-| -} +oldPersian : Generator Char +oldPersian = + char 66464 66527 + + +{-| -} +deseret : Generator Char +deseret = + char 66560 66639 + + +{-| -} +shavian : Generator Char +shavian = + char 66640 66687 + + +{-| -} +osmanya : Generator Char +osmanya = + char 66688 66735 + + +{-| -} +cypriotSyllable : Generator Char +cypriotSyllable = + char 67584 67647 + + +{-| -} +imperialAramaic : Generator Char +imperialAramaic = + char 67648 67679 + + +{-| -} +phoenician : Generator Char +phoenician = + char 67840 67871 + + +{-| -} +lydian : Generator Char +lydian = + char 67872 67903 + + +{-| -} +meroiticHieroglyph : Generator Char +meroiticHieroglyph = + char 67968 67999 + + +{-| -} +meroiticCursive : Generator Char +meroiticCursive = + char 68000 68095 + + +{-| -} +kharoshthi : Generator Char +kharoshthi = + char 68096 68191 + + +{-| -} +oldSouthArabian : Generator Char +oldSouthArabian = + char 68192 68223 + + +{-| -} +avestan : Generator Char +avestan = + char 68352 68415 + + +{-| -} +inscriptionalParthian : Generator Char +inscriptionalParthian = + char 68416 68447 + + +{-| -} +inscriptionalPahlavi : Generator Char +inscriptionalPahlavi = + char 68448 68479 + + +{-| -} +oldTurkic : Generator Char +oldTurkic = + char 68608 68687 + + +{-| -} +rumiNumericalSymbol : Generator Char +rumiNumericalSymbol = + char 69216 69247 + + +{-| -} +brahmi : Generator Char +brahmi = + char 69632 69759 + + +{-| -} +kaithi : Generator Char +kaithi = + char 69760 69839 + + +{-| -} +soraSompeng : Generator Char +soraSompeng = + char 69840 69887 + + +{-| -} +chakma : Generator Char +chakma = + char 69888 69967 + + +{-| -} +sharada : Generator Char +sharada = + char 70016 70111 + + +{-| -} +takri : Generator Char +takri = + char 71296 71375 + + +{-| -} +cuneiform : Generator Char +cuneiform = + char 73728 74751 + + +{-| -} +cuneiformNumberOrPunctuation : Generator Char +cuneiformNumberOrPunctuation = + char 74752 74879 + + +{-| -} +egyptianHieroglyph : Generator Char +egyptianHieroglyph = + char 77824 78895 + + +{-| -} +bamumSupplement : Generator Char +bamumSupplement = + char 92160 92735 + + +{-| -} +miao : Generator Char +miao = + char 93952 94111 + + +{-| -} +kanaSupplement : Generator Char +kanaSupplement = + char 110592 110847 + + +{-| -} +byzantineMusicalSymbol : Generator Char +byzantineMusicalSymbol = + char 118784 119039 + + +{-| -} +musicalSymbol : Generator Char +musicalSymbol = + char 119040 119295 + + +{-| -} +ancientGreekMusicalNotationSymbol : Generator Char +ancientGreekMusicalNotationSymbol = + char 119296 119375 + + +{-| -} +taiXuanJingSymbol : Generator Char +taiXuanJingSymbol = + char 119552 119647 + + +{-| -} +countingRodNumeral : Generator Char +countingRodNumeral = + char 119648 119679 + + +{-| -} +mathematicalAlphanumericSymbol : Generator Char +mathematicalAlphanumericSymbol = + char 119808 120831 + + +{-| -} +arabicMathematicalAlphabeticSymbol : Generator Char +arabicMathematicalAlphabeticSymbol = + char 126464 126719 + + +{-| -} +mahjongTile : Generator Char +mahjongTile = + char 126976 127023 + + +{-| -} +dominoTile : Generator Char +dominoTile = + char 127024 127135 + + +{-| -} +playingCard : Generator Char +playingCard = + char 127136 127231 + + +{-| -} +enclosedAlphanumericSupplement : Generator Char +enclosedAlphanumericSupplement = + char 127232 127487 + + +{-| -} +enclosedIdeographicSupplement : Generator Char +enclosedIdeographicSupplement = + char 127488 127743 + + +{-| -} +miscellaneousSymbolOrPictograph : Generator Char +miscellaneousSymbolOrPictograph = + char 127744 128511 + + +{-| -} +emoticon : Generator Char +emoticon = + char 128512 128591 + + +{-| -} +transportOrMapSymbol : Generator Char +transportOrMapSymbol = + char 128640 128767 + + +{-| -} +alchemicalSymbol : Generator Char +alchemicalSymbol = + char 128768 128895 + + +{-| -} +cjkUnifiedIdeographExtensionB : Generator Char +cjkUnifiedIdeographExtensionB = + char 131072 173791 + + +{-| -} +cjkUnifiedIdeographExtensionC : Generator Char +cjkUnifiedIdeographExtensionC = + char 173824 177983 + + +{-| -} +cjkUnifiedIdeographExtensionD : Generator Char +cjkUnifiedIdeographExtensionD = + char 177984 178207 + + +{-| -} +cjkCompatibilityIdeographSupplement : Generator Char +cjkCompatibilityIdeographSupplement = + char 194560 195103 + + +{-| -} +tag : Generator Char +tag = + char 917504 917631 + + +{-| -} +variationSelectorSupplement : Generator Char +variationSelectorSupplement = + char 917760 917999 + + +{-| -} +supplementaryPrivateUseAreaA : Generator Char +supplementaryPrivateUseAreaA = + char 983040 1048575 + + +{-| -} +supplementaryPrivateUseAreaB : Generator Char +supplementaryPrivateUseAreaB = + char 1048576 1114111 diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Color.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Color.elm new file mode 100644 index 0000000..18c5cc6 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Color.elm @@ -0,0 +1,77 @@ +module Random.Color exposing (..) + +{-| Extra randomized functions on colors. + +# Random Colors by Components +@docs rgb, rgba, hsl, hsla + +# Random Colors by Shade +@docs greyscale, grayscale, red, green, blue + +-} + +import Color exposing (Color) +import Random exposing (Generator, map, map3, map4, int, float) + + +{-| Generate a random non-transparent color by random RGB values. +-} +rgb : Generator Color +rgb = + map3 Color.rgb (int 0 255) (int 0 255) (int 0 255) + + +{-| Generate a random transparent color by random RGBA values. +-} +rgba : Generator Color +rgba = + map4 Color.rgba (int 0 255) (int 0 255) (int 0 255) (float 0 1) + + +{-| Generate a random non-transparent color by random HSL values. +-} +hsl : Generator Color +hsl = + map3 Color.hsl (map degrees (float 0 360)) (float 0 1) (float 0 1) + + +{-| Generate a random transparent color by random HSLA values. +-} +hsla : Generator Color +hsla = + map4 Color.hsla (map degrees (float 0 360)) (float 0 1) (float 0 1) (float 0 1) + + +{-| Generate a random shade of grey +-} +greyscale : Generator Color +greyscale = + map Color.greyscale (float 0 1) + + +{-| Alias for greyscale. +-} +grayscale : Generator Color +grayscale = + greyscale + + +{-| Generate a random shade of red. +-} +red : Generator Color +red = + map (\red -> Color.rgb red 0 0) (int 0 255) + + +{-| Generate a random shade of green. +-} +green : Generator Color +green = + map (\green -> Color.rgb 0 green 0) (int 0 255) + + +{-| Generate a random shade of blue. +-} +blue : Generator Color +blue = + map (\blue -> Color.rgb 0 0 blue) (int 0 255) diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Date.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Date.elm new file mode 100644 index 0000000..6a4b7ac --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Date.elm @@ -0,0 +1,99 @@ +module Random.Date exposing (..) + +{-| Extra randomized functions on dates. + +# Generators +@docs date, day, month, year, hour, hour24, hour12, minute, second + +-} + +import Date exposing (Day(..), Month(..), fromTime, toTime, Date) +import Time exposing (Time) +import Random exposing (Generator, map, int, float) +import Random.Extra exposing (sample) + + +{-| Generate a random day of the week. +-} +day : Generator Day +day = + sample + [ Mon + , Tue + , Wed + , Thu + , Fri + , Sat + , Sun + ] + |> map (Maybe.withDefault Mon) + + +{-| Generate a random month of the year. +-} +month : Generator Month +month = + sample + [ Jan + , Feb + , Mar + , Apr + , May + , Jun + , Jul + , Aug + , Sep + , Oct + , Nov + , Dec + ] + |> map (Maybe.withDefault Jan) + + +{-| Generate a random year given a start year and end year (alias for `int`) +-} +year : Int -> Int -> Generator Int +year = + int + + +{-| Generate a random hour (random int between 0 and 23 inclusive) +-} +hour : Generator Int +hour = + int 0 23 + + +{-| Generate a random 24-hour day hour (random int between 0 and 23 inclusive) +-} +hour24 : Generator Int +hour24 = + int 0 23 + + +{-| Generate a random 12-hour day hour (random int between 0 and 11 inclusive) +-} +hour12 : Generator Int +hour12 = + int 0 11 + + +{-| Generate a random minute (random int between 0 and 59 inclusive) +-} +minute : Generator Int +minute = + int 0 59 + + +{-| Generate a random second (random int between 0 and 59 inclusive) +-} +second : Generator Int +second = + int 0 59 + + +{-| Generate a random date given a start date and an end date. +-} +date : Date -> Date -> Generator Date +date startDate endDate = + map fromTime (float (toTime startDate) (toTime endDate)) diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Dict.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Dict.elm new file mode 100644 index 0000000..cd858ac --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Dict.elm @@ -0,0 +1,28 @@ +module Random.Dict exposing (..) + +{-| Extra randomized functions on dicts. + +# Generators +@docs dict, rangeLengthDict + +-} + +import Dict exposing (Dict, fromList) +import Random exposing (Generator, map, pair, list, int, andThen) + + +{-| Generate a random dict with given length, key generator, and value generator + + randomLength10StringIntDict = dict 10 (englishWord 10) (int 0 100) +-} +dict : Int -> Generator comparable -> Generator value -> Generator (Dict comparable value) +dict dictLength keyGenerator valueGenerator = + map (fromList) (list dictLength (pair keyGenerator valueGenerator)) + + +{-| Generate a random dict of random length given a minimum length and +a maximum length. +-} +rangeLengthDict : Int -> Int -> Generator comparable -> Generator value -> Generator (Dict comparable value) +rangeLengthDict minLength maxLength keyGenerator valueGenerator = + andThen (\len -> dict len keyGenerator valueGenerator) (int minLength maxLength) diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Extra.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Extra.elm new file mode 100644 index 0000000..2484723 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Extra.elm @@ -0,0 +1,354 @@ +module Random.Extra exposing (..) + +{-| This module provides many common and general-purpose helper functions for +core's Random library. You can find even more useful functions for a particular +type in the other modules. + +# Constant Generators +@docs constant + +# Maps +For `map` and `mapN` up through N=5, use the core library. +@docs map6, andMap + +# New Generators +@docs oneIn, maybe, result, choice + +# Working with Lists +@docs choices, frequency, sample, combine, rangeLengthList + +# Filtered Generators +@docs filter + +# andThenN +These functions are like `mapN` except the function you pass in does not return +an exact value, but instead another generator. That means you can take in several +random arguments to drive more randomness. +@docs andThen2, andThen3, andThen4, andThen5, andThen6 +-} + +import Random exposing (Generator, step, list, int, float, bool, map, andThen) + + +{-| Create a generator that always produces the value provided. This is useful +when creating complicated chained generators and you need to handle a simple +case. It's also useful for the base case of recursive generators. +-} +constant : a -> Generator a +constant value = + Random.map (\_ -> value) Random.bool + + +{-| Map a function of six arguments over six generators. +-} +map6 : (a -> b -> c -> d -> e -> f -> g) -> Generator a -> Generator b -> Generator c -> Generator d -> Generator e -> Generator f -> Generator g +map6 f generatorA generatorB generatorC generatorD generatorE generatorF = + Random.map5 f generatorA generatorB generatorC generatorD generatorE |> andMap generatorF + + +{-| Map over any number of generators. + + randomPerson : Generator Person + randomPerson = + map person genFirstName + |> andMap genLastName + |> andMap genBirthday + |> andMap genPhoneNumber + |> andMap genAddress + |> andMap genEmail +-} +andMap : Generator a -> Generator (a -> b) -> Generator b +andMap generator funcGenerator = + Random.map2 (<|) funcGenerator generator + + +{-| Filter a generator so that all generated values satisfy the given predicate. + + evens : Generator Int + evens = + filter (\i -> i % 2 == 0) (int minInt maxInt) + +**Warning:** If the predicate is unsatisfiable, the generator will not +terminate, your application will crash with a stack overflow, and you will be +sad. You should also avoid predicates that are merely very difficult to satisfy. + + badCrashingGenerator = + filter (\_ -> False) anotherGenerator + + likelyCrashingGenerator = + filter (\i -> i % 2000 == 0) (int minInt maxInt) +-} +filter : (a -> Bool) -> Generator a -> Generator a +filter predicate generator = + generator + |> andThen + (\a -> + if predicate a then + constant a + else + filter predicate generator + ) + + +{-| Produce `True` one-in-n times on average. + +Do not pass a value less then one to this function. + + flippedHeads = oneIn 2 + rolled6 = oneIn 6 +-} +oneIn : Int -> Generator Bool +oneIn n = + map ((==) 1) (int 1 n) + + +{-| Choose between two values with equal probability. + + type Flip = Heads | Tails + + coinFlip : Generator Flip + coinFlip = + choice Heads Tails + +Note that this function takes values, not generators. That's because it's meant +to be a lightweight helper for a specific use. If you need to choose between two +generators, use `choices [gen1, gen2]`. +-} +choice : a -> a -> Generator a +choice x y = + map + (\b -> + if b then + x + else + y + ) + bool + + +{-| Create a generator that chooses a generator from a list of generators +with equal probability. + +**Warning:** Do not pass an empty list or your program will crash! In practice +this is usually not a problem since you pass a list literal. +-} +choices : List (Generator a) -> Generator a +choices gens = + frequency <| List.map (\g -> ( 1, g )) gens + + +{-| Create a generator that chooses a generator from a list of generators +based on the provided weight. The likelihood of a given generator being +chosen is its weight divided by the total weight (which doesn't have to equal 1). + +**Warning:** Do not pass an empty list or your program will crash! In practice +this is usually not a problem since you pass a list literal. +-} +frequency : List ( Float, Generator a ) -> Generator a +frequency pairs = + let + total = + List.sum <| List.map (abs << Tuple.first) pairs + + pick choices n = + case choices of + ( k, g ) :: rest -> + if n <= k then + g + else + pick rest (n - k) + + _ -> + Debug.crash "Empty list passed to Random.Extra.frequency!" + in + float 0 total |> andThen (pick pairs) + + +{-| Turn a list of generators into a generator of lists. +-} +combine : List (Generator a) -> Generator (List a) +combine generators = + case generators of + [] -> + constant [] + + g :: gs -> + Random.map2 (::) g (combine gs) + + +{-| Given a list, choose an element uniformly at random. `Nothing` is only +produced if the list is empty. + + type Direction = North | South | East | West + + direction : Generator Direction + direction = + sample [North, South, East, West] + |> map (Maybe.withDefault North) + +-} +sample : List a -> Generator (Maybe a) +sample = + let + find k ys = + case ys of + [] -> + Nothing + + z :: zs -> + if k == 0 then + Just z + else + find (k - 1) zs + in + \xs -> map (\i -> find i xs) (int 0 (List.length xs - 1)) + + +{-| Produce `Just` a value on `True`, and `Nothing` on `False`. + +You can use `bool` or `oneIn n` for the first argument. +-} +maybe : Generator Bool -> Generator a -> Generator (Maybe a) +maybe genBool genA = + genBool + |> andThen + (\b -> + if b then + map Just genA + else + constant Nothing + ) + + +{-| Produce an `Ok` a value on `True`, and an `Err` value on `False`. + +You can use `bool` or `oneIn n` for the first argument. +-} +result : Generator Bool -> Generator err -> Generator val -> Generator (Result err val) +result genBool genErr genVal = + genBool + |> andThen + (\b -> + if b then + map Ok genVal + else + map Err genErr + ) + + +{-| Generate a random list of random length given a minimum length and +a maximum length. +-} +rangeLengthList : Int -> Int -> Generator a -> Generator (List a) +rangeLengthList minLength maxLength generator = + andThen (\len -> list len generator) (int minLength maxLength) + + +{-| -} +andThen2 : (a -> b -> Generator c) -> Generator a -> Generator b -> Generator c +andThen2 constructor generatorA generatorB = + generatorA + |> andThen + (\a -> + generatorB + |> andThen + (\b -> + constructor a b + ) + ) + + +{-| -} +andThen3 : (a -> b -> c -> Generator d) -> Generator a -> Generator b -> Generator c -> Generator d +andThen3 constructor generatorA generatorB generatorC = + generatorA + |> andThen + (\a -> + generatorB + |> andThen + (\b -> + generatorC + |> andThen + (\c -> + constructor a b c + ) + ) + ) + + +{-| -} +andThen4 : (a -> b -> c -> d -> Generator e) -> Generator a -> Generator b -> Generator c -> Generator d -> Generator e +andThen4 constructor generatorA generatorB generatorC generatorD = + generatorA + |> andThen + (\a -> + generatorB + |> andThen + (\b -> + generatorC + |> andThen + (\c -> + generatorD + |> andThen + (\d -> + constructor a b c d + ) + ) + ) + ) + + +{-| -} +andThen5 : (a -> b -> c -> d -> e -> Generator f) -> Generator a -> Generator b -> Generator c -> Generator d -> Generator e -> Generator f +andThen5 constructor generatorA generatorB generatorC generatorD generatorE = + generatorA + |> andThen + (\a -> + generatorB + |> andThen + (\b -> + generatorC + |> andThen + (\c -> + generatorD + |> andThen + (\d -> + generatorE + |> andThen + (\e -> + constructor a b c d e + ) + ) + ) + ) + ) + + +{-| -} +andThen6 : (a -> b -> c -> d -> e -> f -> Generator g) -> Generator a -> Generator b -> Generator c -> Generator d -> Generator e -> Generator f -> Generator g +andThen6 constructor generatorA generatorB generatorC generatorD generatorE generatorF = + generatorA + |> andThen + (\a -> + generatorB + |> andThen + (\b -> + generatorC + |> andThen + (\c -> + generatorD + |> andThen + (\d -> + generatorE + |> andThen + (\e -> + generatorF + |> andThen + (\f -> + constructor a b c d e f + ) + ) + ) + ) + ) + ) diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Float.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Float.elm new file mode 100644 index 0000000..b2907e2 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Float.elm @@ -0,0 +1,67 @@ +module Random.Float exposing (..) + +{-| Extra randomized functions on floats. + +# Arithmetic Generators +@docs anyFloat, positiveFloat, negativeFloat, floatGreaterThan, floatLessThan + +# Gaussian Generators +@docs normal, standardNormal + +-} + +import Random exposing (Generator, map, float, maxInt, minInt) + + +{-| A generator that generates any float +-} +anyFloat : Generator Float +anyFloat = + float (toFloat minInt) (toFloat maxInt) + + +{-| A generator that generates any positive float +-} +positiveFloat : Generator Float +positiveFloat = + float 0 (toFloat maxInt) + + +{-| A generator that generates any negative float +-} +negativeFloat : Generator Float +negativeFloat = + float (toFloat minInt) 0 + + +{-| A generator that generates a float greater than a given float +-} +floatGreaterThan : Float -> Generator Float +floatGreaterThan value = + float value (toFloat maxInt) + + +{-| A generator that generates a float less than a given float +-} +floatLessThan : Float -> Generator Float +floatLessThan value = + float (toFloat minInt) value + + +{-| Create a generator of floats that is normally distributed with +given mean and standard deviation. +-} +normal : Float -> Float -> Generator Float +normal mean stdDev = + map (\u -> u * stdDev + mean) standardNormal + + +{-| A generator that follows a standard normal distribution (as opposed to +a uniform distribution) +-} +standardNormal : Generator Float +standardNormal = + Random.map2 + (\u theta -> sqrt (-2 * logBase e (1 - max 0 u)) * cos theta) + (float 0 1) + (float 0 (2 * pi)) diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Int.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Int.elm new file mode 100644 index 0000000..9081c12 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Int.elm @@ -0,0 +1,45 @@ +module Random.Int exposing (..) + +{-| Extra randomized functions on ints. + +# Generators +@docs anyInt, positiveInt, negativeInt, intGreaterThan, intLessThan +-} + +import Random exposing (Generator, int, minInt, maxInt) + + +{-| A generator that generates any int that can be generated by the +random generator algorithm. +-} +anyInt : Generator Int +anyInt = + int minInt maxInt + + +{-| A generator that generates a positive int +-} +positiveInt : Generator Int +positiveInt = + int 1 maxInt + + +{-| A generator that generates a negative int +-} +negativeInt : Generator Int +negativeInt = + int minInt -1 + + +{-| A generator that generates an int greater than a given int +-} +intGreaterThan : Int -> Generator Int +intGreaterThan value = + int (value + 1) maxInt + + +{-| A generator that generates an int less than a given int +-} +intLessThan : Int -> Generator Int +intLessThan value = + int minInt (value - 1) diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/List.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/List.elm new file mode 100644 index 0000000..e269201 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/List.elm @@ -0,0 +1,75 @@ +module Random.List exposing (choose, shuffle) + +{-| Extra randomized functions on lists. + +# Work with a List +@docs choose, shuffle + +-} + +import Random exposing (Generator, andThen) +import Random.Extra exposing (constant) + + +{-| Get nth element of the list. If the list is empty, the selected element + will be `Nothing`. +-} +get : Int -> List a -> Maybe a +get index list = + list + |> List.drop index + |> List.head + + +{-| Sample without replacement: produce a randomly selected element of the +list, and the list with that element omitted. If the list is empty, the +selected element will be `Nothing`. +-} +choose : List a -> Generator ( Maybe a, List a ) +choose list = + if List.isEmpty list then + constant ( Nothing, list ) + else + let + lastIndex = + List.length list - 1 + + front i = + List.take i list + + back i = + List.drop (i + 1) list + + gen = + Random.int 0 lastIndex + in + Random.map + (\index -> + ( get index list, List.append (front index) (back index) ) + ) + gen + + +{-| Shuffle the list using the Fisher-Yates algorithm. Takes O(_n_ log _n_) +time and O(_n_) additional space. +-} +shuffle : List a -> Generator (List a) +shuffle list = + if List.isEmpty list then + constant list + else + let + helper : ( List a, List a ) -> Generator ( List a, List a ) + helper ( done, remaining ) = + choose remaining + |> andThen + (\( m_val, shorter ) -> + case m_val of + Nothing -> + constant ( done, shorter ) + + Just val -> + helper ( val :: done, shorter ) + ) + in + Random.map Tuple.first (helper ( [], list )) diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Order.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Order.elm new file mode 100644 index 0000000..5031474 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Order.elm @@ -0,0 +1,21 @@ +module Random.Order exposing (..) + +{-| An extra random generator for the `Order` type. + +@docs order +-} + +import Random exposing (Generator, map) +import Random.Extra exposing (sample) + + +{-| Generate a random order with equal probability. +-} +order : Generator Order +order = + sample + [ LT + , EQ + , GT + ] + |> map (Maybe.withDefault EQ) diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Set.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Set.elm new file mode 100644 index 0000000..3fb7256 --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/Set.elm @@ -0,0 +1,62 @@ +module Random.Set exposing (..) + +{-| Extra randomized functions on sets. + +# Create a Set +@docs set + +# Create a Generator +@docs sample + +# Modify a Generator +@docs notInSet + +-} + +import Set exposing (Set) +import Random exposing (Generator, map, andThen) +import Random.Extra exposing (constant, filter) + + +{-| Filter a generator of all values not in a given set. +-} +notInSet : Set comparable -> Generator comparable -> Generator comparable +notInSet set generator = + filter (not << flip Set.member set) generator + + +{-| Select a value from a set uniformly at random, or `Nothing` for an empty set. +Analogous to `Random.Extra.sample` but with sets. +-} +sample : Set comparable -> Generator (Maybe comparable) +sample set = + Random.Extra.sample (Set.toList set) + + +{-| Generate a set of at most the given size from a generator. + +The size of a generated set is limited both by the integer provided and the +number of unique values the generator can produce. It is very likely, but not +guaranteed, that generated sets will be as big as the smaller of these two limits. +-} +set : Int -> Generator comparable -> Generator (Set comparable) +set maxLength generator = + let + helper set remaining strikes = + if remaining <= 0 || strikes == 10 then + constant set + else + generator + |> andThen + (\val -> + let + newSet = + Set.insert val set + in + if Set.size newSet == Set.size set then + helper set remaining (strikes + 1) + else + helper newSet (remaining - 1) 0 + ) + in + helper Set.empty maxLength 0 diff --git a/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/String.elm b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/String.elm new file mode 100644 index 0000000..29e0feb --- /dev/null +++ b/client/elm-stuff/packages/elm-community/random-extra/2.0.0/src/Random/String.elm @@ -0,0 +1,28 @@ +module Random.String exposing (..) + +{-| Extra randomized functions on strings. + +# Create a String +@docs string, rangeLengthString + +-} + +import String exposing (fromList) +import Random exposing (Generator, map, map2, list, int, andThen) + + +{-| Generate a random string of a given length with a given character generator + + fiveLetterEnglishWord = string 5 Random.Char.english +-} +string : Int -> Generator Char -> Generator String +string stringLength charGenerator = + map fromList (list stringLength charGenerator) + + +{-| Generates a random string of random length given the minimum length +and maximum length and a given character generator. +-} +rangeLengthString : Int -> Int -> Generator Char -> Generator String +rangeLengthString minLength maxLength charGenerator = + andThen (\len -> string len charGenerator) (int minLength maxLength) diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/.eslintrc b/client/elm-stuff/packages/elm-lang/core/5.1.1/.eslintrc new file mode 100644 index 0000000..169879a --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/.eslintrc @@ -0,0 +1,156 @@ +{ + "parser": "babel-eslint", // https://github.com/babel/babel-eslint + "plugins": [], + "env": { // http://eslint.org/docs/user-guide/configuring.html#specifying-environments + "browser": true, // browser global variables + "node": true // Node.js global variables and Node.js-specific rules + }, + "ecmaFeatures": { + "arrowFunctions": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "forOf": true, + "generators": false, + "modules": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": false, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "spread": true, + "superInFunctions": true, + "templateStrings": true, + }, + "rules": { +/** + * Strict mode + */ + // babel inserts "use strict"; for us + "strict": [2, "never"], // http://eslint.org/docs/rules/strict + +/** + * Variables + */ + "no-shadow": 2, // http://eslint.org/docs/rules/no-shadow + "no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names + "no-unused-vars": [2, { // http://eslint.org/docs/rules/no-unused-vars + "vars": "local", + "args": "after-used" + }], + "no-use-before-define": 2, // http://eslint.org/docs/rules/no-use-before-define + +/** + * Possible errors + */ + "no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign + "no-console": 1, // http://eslint.org/docs/rules/no-console + "no-debugger": 1, // http://eslint.org/docs/rules/no-debugger + "no-alert": 1, // http://eslint.org/docs/rules/no-alert + "no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition + "no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys + "no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case + "no-empty": 2, // http://eslint.org/docs/rules/no-empty + "no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign + "no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast + "no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi + "no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign + "no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations + "no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp + "no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace + "no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls + "no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays + "no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable + "use-isnan": 2, // http://eslint.org/docs/rules/use-isnan + "block-scoped-var": 2, // http://eslint.org/docs/rules/block-scoped-var + +/** + * Best practices + */ + "consistent-return": 2, // http://eslint.org/docs/rules/consistent-return + "curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly + "default-case": 2, // http://eslint.org/docs/rules/default-case + "dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation + "allowKeywords": true + }], + "eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq + "max-len": [2, 100, 4], + "guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in + "no-caller": 2, // http://eslint.org/docs/rules/no-caller + "no-else-return": 2, // http://eslint.org/docs/rules/no-else-return + "no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null + "no-eval": 2, // http://eslint.org/docs/rules/no-eval + "no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native + "no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind + "no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough + "no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal + "no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval + "no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks + "no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func + "no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str + "no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign + "no-new": 2, // http://eslint.org/docs/rules/no-new + "no-new-func": 2, // http://eslint.org/docs/rules/no-new-func + "no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers + "no-octal": 2, // http://eslint.org/docs/rules/no-octal + "no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape + "no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign + "no-proto": 2, // http://eslint.org/docs/rules/no-proto + "no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare + "no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign + "no-script-url": 2, // http://eslint.org/docs/rules/no-script-url + "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare + "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences + "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal + "no-with": 2, // http://eslint.org/docs/rules/no-with + "radix": 2, // http://eslint.org/docs/rules/radix + "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife + "yoda": 2, // http://eslint.org/docs/rules/yoda + +/** + * Style + */ + "indent": [2, "tab"], // http://eslint.org/docs/rules/indent + "quotes": [ + 2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes + ], + "camelcase": [2, { // http://eslint.org/docs/rules/camelcase + "properties": "never" + }], + "comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing + "before": false, + "after": true + }], + "comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style + "eol-last": 2, // http://eslint.org/docs/rules/eol-last + "func-names": 1, // http://eslint.org/docs/rules/func-names + "key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing + "beforeColon": false, + "afterColon": true + }], + "no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines + "max": 2 + }], + "no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary + "no-new-object": 2, // http://eslint.org/docs/rules/no-new-object + "no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func + "no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces + "no-extra-parens": [2, "functions"], // http://eslint.org/docs/rules/no-extra-parens + "no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle + "padded-blocks": [2, "never"], // http://eslint.org/docs/rules/padded-blocks + "semi": [2, "always"], // http://eslint.org/docs/rules/semi + "semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing + "before": false, + "after": true + }], + "space-after-keywords": 2, // http://eslint.org/docs/rules/space-after-keywords + "space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks + "space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren + "space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops + "space-return-throw-case": 2, // http://eslint.org/docs/rules/space-return-throw-case + "spaced-comment": [2, "always", {// http://eslint.org/docs/rules/spaced-comment + "exceptions": ["-", "+"], + "markers": ["=", "!"] // space here to support sprockets directives + }] + } +} diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/.gitignore b/client/elm-stuff/packages/elm-lang/core/5.1.1/.gitignore new file mode 100644 index 0000000..7f3cfe4 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/.gitignore @@ -0,0 +1,3 @@ +elm-stuff +tests/test.js +node_modules/ \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/.travis.yml b/client/elm-stuff/packages/elm-lang/core/5.1.1/.travis.yml new file mode 100644 index 0000000..9576ae8 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/.travis.yml @@ -0,0 +1,35 @@ +sudo: false + +cache: + directories: + - test/elm-stuff/build-artifacts + - sysconfcpus + +language: node_js + +node_js: + - "4.3" + +before_install: + - if [ ${TRAVIS_OS_NAME} == "osx" ]; + then brew update; brew install nvm; mkdir ~/.nvm; export NVM_DIR=~/.nvm; source $(brew --prefix nvm)/nvm.sh; + fi + - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + - | # epic build time improvement - see https://github.com/elm-lang/elm-compiler/issues/1473#issuecomment-245704142 + if [ ! -d sysconfcpus/bin ]; + then + git clone https://github.com/obmarg/libsysconfcpus.git; + cd libsysconfcpus; + ./configure --prefix=$TRAVIS_BUILD_DIR/sysconfcpus; + make && make install; + cd ..; + fi + +install: + - npm install -g elm@0.18 elm-test + - mv $(npm config get prefix)/bin/elm-make $(npm config get prefix)/bin/elm-make-old + - printf '%s\n\n' '#!/bin/bash' 'echo "Running elm-make with sysconfcpus -n 2"' '$TRAVIS_BUILD_DIR/sysconfcpus/bin/sysconfcpus -n 2 elm-make-old "$@"' > $(npm config get prefix)/bin/elm-make + - chmod +x $(npm config get prefix)/bin/elm-make + +script: + - bash tests/run-tests.sh diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/CONTRIBUTING.md b/client/elm-stuff/packages/elm-lang/core/5.1.1/CONTRIBUTING.md new file mode 100644 index 0000000..c8bd8b4 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing to the core libraries + +Thanks helping with the development of Elm! This document describes the basic +standards for opening pull requests and making the review process as smooth as +possible. + +## Ground rules + + * Always make pull requests minimal. If it can be split up, it should be split up. + * Use style consistent with the file you are modifying. + * Use descriptive titles for PRs + * Provide all the necessary context for evaluation in the PR. + If there are relevant issues or examples or discussions, add them. + If things can be summarized, summarize them. The easiest PRs are ones + that already address the reviewers questions and concerns. + +## Documentation Fixes + +If you want to fix docs, just open a PR. This is super helpful! + +## Bug Fixes + +If you find an issue or see one you want to work on, go for it! + +The best strategy is often to dive in. Asking for directions usually +does not work. If someone knew the specifics and knew how how to fix +it, it is likely they would have already sent the PR themselves! + +Also, be sure you are testing. + +## Adding New Functions + +We are fairly conservative about adding new functions to core libraries. +If you want to augment the `List` or `Array` library, we recommend creating +small packages called `list-extras` or `array-extras` that have all the +features you want. There are already several such packages maintained at +the [Elm Community organization](https://github.com/elm-community) that +welcome contributions in the form of pull requests. + +Long term, we will set up a process to review `*-extras` packages to move +stuff into core. By going through packages, it will be much easier to assess +whether a function is pleasant and useful in practice before committing to it +in the core libraries. diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/LICENSE b/client/elm-stuff/packages/elm-lang/core/5.1.1/LICENSE new file mode 100644 index 0000000..e0419a4 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2014-present, Evan Czaplicki + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of Evan Czaplicki nor the names of other + 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 +OWNER 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. diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/README.md b/client/elm-stuff/packages/elm-lang/core/5.1.1/README.md new file mode 100644 index 0000000..07c3f6e --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/README.md @@ -0,0 +1,34 @@ +# Elm Core Libraries + +[![Build Status](https://travis-ci.org/elm-lang/core.svg?branch=master)](https://travis-ci.org/elm-lang/core) + +Every Elm project needs the core libraries. They provide basic functionality including: + + * The Basics — addition, subtraction, etc. + * Data Structures — lists, dictionaries, sets, etc. + + +## Default Imports + +All Elm files have some default imports: + +```elm +import Basics exposing (..) +import List exposing ( List, (::) ) +import Maybe exposing ( Maybe( Just, Nothing ) ) +import Result exposing ( Result( Ok, Err ) ) +import String +import Tuple + +import Debug + +import Platform exposing ( Program ) +import Platform.Cmd exposing ( Cmd, (!) ) +import Platform.Sub exposing ( Sub ) +``` + +The intention is to include things that are both extremely useful and very +unlikely to overlap with anything that anyone will ever write in a library. +By keeping the set of default imports small, it also becomes easier to use +whatever version of `map` suits your fancy. Finally, it makes it easier to +figure out where the heck a function is coming from. diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/changelog.md b/client/elm-stuff/packages/elm-lang/core/5.1.1/changelog.md new file mode 100644 index 0000000..9781f2c --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/changelog.md @@ -0,0 +1,143 @@ +# 0.15 + +### Syntax + +New `import` syntax with keyword `exposing`. + +### Module Changes + + * Move `Http` to `elm-http` package and totally redo API + * Remove `WebSocket` module + * Add `Task` module + +### Channels become Mailboxes + +`Graphics.Input` now works with this API (from module `Signal`): + +```elm +type alias Mailbox a = { address : Address a, signal : Signal a } + +mailbox : a -> Mailbox a +``` + +You can then send messages to the `Address` with functions like `Signal.send` +and `Signal.message`, or create forwarding addresses with `Signal.forwardTo`. + +### Text in Collages + +`Graphics.Collage` now has two new functions: + +```elm +text : Text -> Form +outlinedText : LineStyle -> Text -> Form +``` + +These functions render text with the canvas, making things quite a bit faster. +The underlying implementation of `Text` has also been improved dramatically. + +### Miscellaneous + + * Change types of `head`, `tail`, `maximum`, `minimum` by wrapping output in `Maybe` + * Move `leftAligned`, `centered`, `rightAligned` from `Text` to `Graphics.Element` + * Move `asText` from `Text` to `Graphics.Element`, renaming it to `show` in the process + * Remove `Text.plainText` (can be replaced by `Graphics.Element.leftAligned << Text.fromString`) + * Change type of `Keyboard.keysDown` from `Signal (List KeyCode)` to `Signal (Set KeyCode)` + * Remove `Keyboard.directions` + * Rename `Keyboard.lastPressed` to `Keyboard.presses` + + +# 0.14 + +### Syntax + + * Keyword `type` becomes `type alias` + * Keyword `data` becomes `type` + * Remove special list syntax in types, so `[a]` becomes `List a` + + +### Reduce Default Imports + +The set of default imports has been reduced to the following: + +```haskell +import Basics (..) +import Maybe ( Maybe( Just, Nothing ) ) +import Result ( Result( Ok, Err ) ) +import List ( List ) +import Signal ( Signal ) +``` + +### Make JSON parsing easy + + * Added `Json.Decode` and `Json.Encode` libraries + + +### Use more natural names + + * Rename `String.show` to `String.toString` + + * Replace `List.zip` with `List.map2 (,)` + * Replace `List.zipWith f` with `List.map2 f` + + * Rename `Signal.liftN` to `Signal.mapN` + * Rename `Signal.merges` to `Signal.mergeMany` + + +### Simplify Signal Library + + * Revamp `Input` concept as `Signal.Channel` + * Remove `Signal.count` + * Remove `Signal.countIf` + * Remove `Signal.combine` + + +### Randomness Done Right + + * No longer signal-based + * Use a `Generator` to create random values + + + +### Revamp Maybes and Error Handling + + * Add the following functions to `Maybe` + + withDefault : a -> Maybe a -> a + oneOf : List (Maybe a) -> Maybe a + map : (a -> b) -> Maybe a -> Maybe b + andThen : Maybe a -> (a -> Maybe b) -> Maybe b + + * Remove `Maybe.maybe` so `maybe 0 sqrt Nothing` becomes `withDefault 0 (map sqrt Nothing)` + + * Remove `Maybe.isJust` and `Maybe.isNothing` in favor of pattern matching + + * Add `Result` library for proper error handling. This is for cases when + you want a computation to succeed, but if there is a mistake, it should + produce a nice error message. + + * Remove `Either` in favor of `Result` or custom union types + + * Revamp functions that result in a `Maybe`. + + - Remove `Dict.getOrElse` and `Dict.getOrFail` in favor of `withDefault 0 (Dict.get key dict)` + - Remove `Array.getOrElse` and `Array.getOrFail` in favor of `withDefault 0 (Array.get index array)` + - Change `String.toInt : String -> Maybe Int` to `String.toInt : String -> Result String Int` + - Change `String.toFloat : String -> Maybe Float` to `String.toFloat : String -> Result String Float` + + +### Make appending more logical + + * Add the following functions to `Text`: + + empty : Text + append : Text -> Text -> Text + concat : [Text] -> Text + join : Text -> [Text] -> Text + + * Make the following changes in `List`: + - Replace `(++)` with `append` + - Remove `join` + +### Miscellaneous + + * Rename `Text.toText` to `Text.fromString` diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/elm-package.json b/client/elm-stuff/packages/elm-lang/core/5.1.1/elm-package.json new file mode 100644 index 0000000..2f25729 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/elm-package.json @@ -0,0 +1,38 @@ +{ + "version": "5.1.1", + "summary": "Elm's standard libraries", + "repository": "http://github.com/elm-lang/core.git", + "license": "BSD3", + "source-directories": [ + "src" + ], + "exposed-modules": [ + "Array", + "Basics", + "Bitwise", + "Char", + "Color", + "Date", + "Debug", + "Dict", + "Json.Decode", + "Json.Encode", + "List", + "Maybe", + "Platform", + "Platform.Cmd", + "Platform.Sub", + "Process", + "Random", + "Regex", + "Result", + "Set", + "String", + "Task", + "Time", + "Tuple" + ], + "native-modules": true, + "dependencies": {}, + "elm-version": "0.18.0 <= v < 0.19.0" +} diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Array.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Array.elm new file mode 100644 index 0000000..58ae2ba --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Array.elm @@ -0,0 +1,240 @@ +module Array exposing + ( Array + , empty, repeat, initialize, fromList + , isEmpty, length, push, append + , get, set + , slice, toList, toIndexedList + , map, indexedMap, filter, foldl, foldr + ) + +{-| A library for fast immutable arrays. The elements in an array must have the +same type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast +reads, updates, and appends. + +# Arrays +@docs Array + +# Creating Arrays +@docs empty, repeat, initialize, fromList + +# Basics +@docs isEmpty, length, push, append + +# Get and Set +@docs get, set + +# Taking Arrays Apart +@docs slice, toList, toIndexedList + +# Mapping, Filtering, and Folding +@docs map, indexedMap, filter, foldl, foldr +-} + +import Native.Array +import Basics exposing (..) +import Maybe exposing (..) +import List + + +{-| Representation of fast immutable arrays. You can create arrays of integers +(`Array Int`) or strings (`Array String`) or any other type of value you can +dream up. +-} +type Array a = Array + + +{-| Initialize an array. `initialize n f` creates an array of length `n` with +the element at index `i` initialized to the result of `(f i)`. + + initialize 4 identity == fromList [0,1,2,3] + initialize 4 (\n -> n*n) == fromList [0,1,4,9] + initialize 4 (always 0) == fromList [0,0,0,0] +-} +initialize : Int -> (Int -> a) -> Array a +initialize = + Native.Array.initialize + + +{-| Creates an array with a given length, filled with a default element. + + repeat 5 0 == fromList [0,0,0,0,0] + repeat 3 "cat" == fromList ["cat","cat","cat"] + +Notice that `repeat 3 x` is the same as `initialize 3 (always x)`. +-} +repeat : Int -> a -> Array a +repeat n e = + initialize n (always e) + + +{-| Create an array from a list. +-} +fromList : List a -> Array a +fromList = + Native.Array.fromList + + +{-| Create a list of elements from an array. + + toList (fromList [3,5,8]) == [3,5,8] +-} +toList : Array a -> List a +toList = + Native.Array.toList + + +-- TODO: make this a native function. +{-| Create an indexed list from an array. Each element of the array will be +paired with its index. + + toIndexedList (fromList ["cat","dog"]) == [(0,"cat"), (1,"dog")] +-} +toIndexedList : Array a -> List (Int, a) +toIndexedList array = + List.map2 + (,) + (List.range 0 (Native.Array.length array - 1)) + (Native.Array.toList array) + + +{-| Apply a function on every element in an array. + + map sqrt (fromList [1,4,9]) == fromList [1,2,3] +-} +map : (a -> b) -> Array a -> Array b +map = + Native.Array.map + + +{-| Apply a function on every element with its index as first argument. + + indexedMap (*) (fromList [5,5,5]) == fromList [0,5,10] +-} +indexedMap : (Int -> a -> b) -> Array a -> Array b +indexedMap = + Native.Array.indexedMap + + +{-| Reduce an array from the left. Read `foldl` as “fold from the left”. + + foldl (::) [] (fromList [1,2,3]) == [3,2,1] +-} +foldl : (a -> b -> b) -> b -> Array a -> b +foldl = + Native.Array.foldl + + +{-| Reduce an array from the right. Read `foldr` as “fold from the right”. + + foldr (+) 0 (repeat 3 5) == 15 +-} +foldr : (a -> b -> b) -> b -> Array a -> b +foldr = + Native.Array.foldr + + +{-| Keep only elements that satisfy the predicate: + + filter isEven (fromList [1,2,3,4,5,6]) == (fromList [2,4,6]) +-} +filter : (a -> Bool) -> Array a -> Array a +filter isOkay arr = + let + update x xs = + if isOkay x then + Native.Array.push x xs + else + xs + in + Native.Array.foldl update Native.Array.empty arr + +{-| Return an empty array. + + length empty == 0 +-} +empty : Array a +empty = + Native.Array.empty + + +{-| Push an element to the end of an array. + + push 3 (fromList [1,2]) == fromList [1,2,3] +-} +push : a -> Array a -> Array a +push = + Native.Array.push + + +{-| Return Just the element at the index or Nothing if the index is out of range. + + get 0 (fromList [0,5,3]) == Just 0 + get 2 (fromList [0,5,3]) == Just 3 + get 5 (fromList [0,5,3]) == Nothing + get -1 (fromList [0,5,3]) == Nothing + +-} +get : Int -> Array a -> Maybe a +get i array = + if 0 <= i && i < Native.Array.length array then + Just (Native.Array.get i array) + else + Nothing + + +{-| Set the element at a particular index. Returns an updated array. +If the index is out of range, the array is unaltered. + + set 1 7 (fromList [1,2,3]) == fromList [1,7,3] +-} +set : Int -> a -> Array a -> Array a +set = + Native.Array.set + + +{-| Get a sub-section of an array: `(slice start end array)`. The `start` is a +zero-based index where we will start our slice. The `end` is a zero-based index +that indicates the end of the slice. The slice extracts up to but not including +`end`. + + slice 0 3 (fromList [0,1,2,3,4]) == fromList [0,1,2] + slice 1 4 (fromList [0,1,2,3,4]) == fromList [1,2,3] + +Both the `start` and `end` indexes can be negative, indicating an offset from +the end of the array. + + slice 1 -1 (fromList [0,1,2,3,4]) == fromList [1,2,3] + slice -2 5 (fromList [0,1,2,3,4]) == fromList [3,4] + +This makes it pretty easy to `pop` the last element off of an array: `slice 0 -1 array` +-} +slice : Int -> Int -> Array a -> Array a +slice = + Native.Array.slice + + +{-| Return the length of an array. + + length (fromList [1,2,3]) == 3 +-} +length : Array a -> Int +length = + Native.Array.length + + +{-| Determine if an array is empty. + + isEmpty empty == True +-} +isEmpty : Array a -> Bool +isEmpty array = + length array == 0 + + +{-| Append two arrays to a new one. + + append (repeat 2 42) (repeat 3 81) == fromList [42,42,81,81,81] +-} +append : Array a -> Array a -> Array a +append = + Native.Array.append diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Basics.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Basics.elm new file mode 100644 index 0000000..2d06c86 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Basics.elm @@ -0,0 +1,650 @@ +module Basics exposing + ( (==), (/=) + , (<), (>), (<=), (>=), max, min, Order (..), compare + , not, (&&), (||), xor + , (+), (-), (*), (/), (^), (//), rem, (%), negate, abs, sqrt, clamp, logBase, e + , pi, cos, sin, tan, acos, asin, atan, atan2 + , round, floor, ceiling, truncate, toFloat + , degrees, radians, turns + , toPolar, fromPolar + , isNaN, isInfinite + , toString, (++) + , identity, always, (<|), (|>), (<<), (>>), flip, curry, uncurry, Never, never + ) + +{-| Tons of useful functions that get imported by default. + +# Equality +@docs (==), (/=) + +# Comparison + +These functions only work on `comparable` types. This includes numbers, +characters, strings, lists of comparable things, and tuples of comparable +things. Note that tuples with 7 or more elements are not comparable; why +are your tuples so big? + +@docs (<), (>), (<=), (>=), max, min, Order, compare + +# Booleans +@docs not, (&&), (||), xor + +# Mathematics +@docs (+), (-), (*), (/), (^), (//), rem, (%), negate, abs, sqrt, clamp, logBase, e + +# Trigonometry +@docs pi, cos, sin, tan, acos, asin, atan, atan2 + +# Number Conversions +@docs round, floor, ceiling, truncate, toFloat + +# Angle Conversions +All angle conversions result in “standard Elm angles” +which happen to be radians. + +@docs degrees, radians, turns + +# Polar Coordinates +@docs toPolar, fromPolar + +# Floating Point Checks +@docs isNaN, isInfinite + +# Strings and Lists +@docs toString, (++) + +# Higher-Order Helpers +@docs identity, always, (<|), (|>), (<<), (>>), flip, curry, uncurry, Never, never + +-} + +import Native.Basics +import Native.Utils + + +{-| Convert radians to standard Elm angles (radians). -} +radians : Float -> Float +radians t = + t + + +{-| Convert degrees to standard Elm angles (radians). -} +degrees : Float -> Float +degrees = + Native.Basics.degrees + + +{-| Convert turns to standard Elm angles (radians). +One turn is equal to 360°. +-} +turns : Float -> Float +turns = + Native.Basics.turns + + +{-| Convert polar coordinates (r,θ) to Cartesian coordinates (x,y). -} +fromPolar : (Float,Float) -> (Float,Float) +fromPolar = + Native.Basics.fromPolar + + +{-| Convert Cartesian coordinates (x,y) to polar coordinates (r,θ). -} +toPolar : (Float,Float) -> (Float,Float) +toPolar = + Native.Basics.toPolar + + +{-|-} +(+) : number -> number -> number +(+) = + Native.Basics.add + + +{-|-} +(-) : number -> number -> number +(-) = + Native.Basics.sub + + +{-|-} +(*) : number -> number -> number +(*) = + Native.Basics.mul + + +{-| Floating point division. -} +(/) : Float -> Float -> Float +(/) = + Native.Basics.floatDiv + + +infixl 6 + +infixl 6 - +infixl 7 * +infixl 7 / +infixr 8 ^ + +infixl 7 // +infixl 7 % + + +{-| Integer division. The remainder is discarded. -} +(//) : Int -> Int -> Int +(//) = + Native.Basics.div + + +{-| Find the remainder after dividing one number by another. + + rem 11 4 == 3 + rem 12 4 == 0 + rem 13 4 == 1 + rem -1 4 == -1 +-} +rem : Int -> Int -> Int +rem = + Native.Basics.rem + + +{-| Perform [modular arithmetic](http://en.wikipedia.org/wiki/Modular_arithmetic). + + 7 % 2 == 1 + -1 % 4 == 3 +-} +(%) : Int -> Int -> Int +(%) = + Native.Basics.mod + + +{-| Exponentiation + + 3^2 == 9 +-} +(^) : number -> number -> number +(^) = + Native.Basics.exp + + +{-|-} +cos : Float -> Float +cos = + Native.Basics.cos + + +{-|-} +sin : Float -> Float +sin = + Native.Basics.sin + + +{-|-} +tan : Float -> Float +tan = + Native.Basics.tan + + +{-|-} +acos : Float -> Float +acos = + Native.Basics.acos + + +{-|-} +asin : Float -> Float +asin = + Native.Basics.asin + + +{-| You probably do not want to use this. It takes `(y/x)` as the +argument, so there is no way to know whether the negative signs comes from +the `y` or `x`. Thus, the resulting angle is always between π/2 and -π/2 +(in quadrants I and IV). You probably want to use `atan2` instead. +-} +atan : Float -> Float +atan = + Native.Basics.atan + + +{-| This helps you find the angle of a Cartesian coordinate. +You will almost certainly want to use this instead of `atan`. +So `atan2 y x` computes *atan(y/x)* but also keeps track of which +quadrant the angle should really be in. The result will be between +π and -π, giving you the full range of angles. +-} +atan2 : Float -> Float -> Float +atan2 = + Native.Basics.atan2 + + +{-| Take the square root of a number. -} +sqrt : Float -> Float +sqrt = + Native.Basics.sqrt + + +{-| Negate a number. + + negate 42 == -42 + negate -42 == 42 + negate 0 == 0 +-} +negate : number -> number +negate = + Native.Basics.negate + + +{-| Take the absolute value of a number. -} +abs : number -> number +abs = + Native.Basics.abs + + +{-| Calculate the logarithm of a number with a given base. + + logBase 10 100 == 2 + logBase 2 256 == 8 +-} +logBase : Float -> Float -> Float +logBase = + Native.Basics.logBase + + +{-| Clamps a number within a given range. With the expression +`clamp 100 200 x` the results are as follows: + + 100 if x < 100 + x if 100 <= x < 200 + 200 if 200 <= x +-} +clamp : number -> number -> number -> number +clamp = + Native.Basics.clamp + + +{-| An approximation of pi. -} +pi : Float +pi = + Native.Basics.pi + + +{-| An approximation of e. -} +e : Float +e = + Native.Basics.e + + +{-| Check if values are “the same”. + +**Note:** Elm uses structural equality on tuples, records, and user-defined +union types. This means the values `(3, 4)` and `(3, 4)` are definitely equal. +This is not true in languages like JavaScript that use reference equality on +objects. + +**Note:** Equality (in the Elm sense) is not possible for certain types. For +example, the functions `(\n -> n + 1)` and `(\n -> 1 + n)` are “the +same” but detecting this in general is [undecidable][]. In a future +release, the compiler will detect when `(==)` is used with problematic +types and provide a helpful error message. This will require quite serious +infrastructure work that makes sense to batch with another big project, so the +stopgap is to crash as quickly as possible. Problematic types include functions +and JavaScript values like `Json.Encode.Value` which could contain functions +if passed through a port. + +[undecidable]: https://en.wikipedia.org/wiki/Undecidable_problem +-} +(==) : a -> a -> Bool +(==) = + Native.Basics.eq + + +{-| Check if values are not “the same”. + +So `(a /= b)` is the same as `(not (a == b))`. +-} +(/=) : a -> a -> Bool +(/=) = + Native.Basics.neq + + +{-|-} +(<) : comparable -> comparable -> Bool +(<) = + Native.Basics.lt + + +{-|-} +(>) : comparable -> comparable -> Bool +(>) = + Native.Basics.gt + + +{-|-} +(<=) : comparable -> comparable -> Bool +(<=) = + Native.Basics.le + + +{-|-} +(>=) : comparable -> comparable -> Bool +(>=) = + Native.Basics.ge + + +infix 4 == +infix 4 /= +infix 4 < +infix 4 > +infix 4 <= +infix 4 >= + + +{-| Compare any two comparable values. Comparable values include `String`, `Char`, +`Int`, `Float`, `Time`, or a list or tuple containing comparable values. +These are also the only values that work as `Dict` keys or `Set` members. +-} +compare : comparable -> comparable -> Order +compare = + Native.Basics.compare + + +{-| Represents the relative ordering of two things. +The relations are less than, equal to, and greater than. +-} +type Order = LT | EQ | GT + + +{-| Find the smaller of two comparables. -} +min : comparable -> comparable -> comparable +min = + Native.Basics.min + + +{-| Find the larger of two comparables. -} +max : comparable -> comparable -> comparable +max = + Native.Basics.max + + +{-| The logical AND operator. `True` if both inputs are `True`. + +**Note:** When used in the infix position, like `(left && right)`, the operator +short-circuits. This means if `left` is `False` we do not bother evaluating `right` +and just return `False` overall. +-} +(&&) : Bool -> Bool -> Bool +(&&) = + Native.Basics.and + + +{-| The logical OR operator. `True` if one or both inputs are `True`. + +**Note:** When used in the infix position, like `(left || right)`, the operator +short-circuits. This means if `left` is `True` we do not bother evaluating `right` +and just return `True` overall. +-} +(||) : Bool -> Bool -> Bool +(||) = + Native.Basics.or + + +infixr 3 && +infixr 2 || + + +{-| The exclusive-or operator. `True` if exactly one input is `True`. -} +xor : Bool -> Bool -> Bool +xor = + Native.Basics.xor + + +{-| Negate a boolean value. + + not True == False + not False == True +-} +not : Bool -> Bool +not = + Native.Basics.not + + +-- Conversions + +{-| Round a number to the nearest integer. -} +round : Float -> Int +round = + Native.Basics.round + + +{-| Truncate a number, rounding towards zero. -} +truncate : Float -> Int +truncate = + Native.Basics.truncate + + +{-| Floor function, rounding down. -} +floor : Float -> Int +floor = + Native.Basics.floor + + +{-| Ceiling function, rounding up. -} +ceiling : Float -> Int +ceiling = + Native.Basics.ceiling + + +{-| Convert an integer into a float. -} +toFloat : Int -> Float +toFloat = + Native.Basics.toFloat + + +{-| Determine whether a float is an undefined or unrepresentable number. +NaN stands for *not a number* and it is [a standardized part of floating point +numbers](http://en.wikipedia.org/wiki/NaN). + + isNaN (0/0) == True + isNaN (sqrt -1) == True + isNaN (1/0) == False -- infinity is a number + isNaN 1 == False +-} +isNaN : Float -> Bool +isNaN = + Native.Basics.isNaN + + +{-| Determine whether a float is positive or negative infinity. + + isInfinite (0/0) == False + isInfinite (sqrt -1) == False + isInfinite (1/0) == True + isInfinite 1 == False + +Notice that NaN is not infinite! For float `n` to be finite implies that +`not (isInfinite n || isNaN n)` evaluates to `True`. +-} +isInfinite : Float -> Bool +isInfinite = + Native.Basics.isInfinite + + +{-| Turn any kind of value into a string. When you view the resulting string +with `Text.fromString` it should look just like the value it came from. + + toString 42 == "42" + toString [1,2] == "[1,2]" + toString "he said, \"hi\"" == "\"he said, \\\"hi\\\"\"" +-} +toString : a -> String +toString = + Native.Utils.toString + + +{-| Put two appendable things together. This includes strings, lists, and text. + + "hello" ++ "world" == "helloworld" + [1,1,2] ++ [3,5,8] == [1,1,2,3,5,8] +-} +(++) : appendable -> appendable -> appendable +(++) = + Native.Utils.append + + +infixr 5 ++ + + +-- Function Helpers + +{-| Function composition, passing results along in the suggested direction. For +example, the following code checks if the square root of a number is odd: + + not << isEven << sqrt + +You can think of this operator as equivalent to the following: + + (g << f) == (\x -> g (f x)) + +So our example expands out to something like this: + + \n -> not (isEven (sqrt n)) +-} +(<<) : (b -> c) -> (a -> b) -> (a -> c) +(<<) g f x = + g (f x) + + +{-| Function composition, passing results along in the suggested direction. For +example, the following code checks if the square root of a number is odd: + + sqrt >> isEven >> not + +This direction of function composition seems less pleasant than `(<<)` which +reads nicely in expressions like: `filter (not << isRegistered) students` +-} +(>>) : (a -> b) -> (b -> c) -> (a -> c) +(>>) f g x = + g (f x) + + +{-| Forward function application `x |> f == f x`. This function is useful +for avoiding parentheses and writing code in a more natural way. +Consider the following code to create a pentagon: + + scale 2 (move (10,10) (filled blue (ngon 5 30))) + +This can also be written as: + + ngon 5 30 + |> filled blue + |> move (10,10) + |> scale 2 +-} +(|>) : a -> (a -> b) -> b +(|>) x f = + f x + + +{-| Backward function application `f <| x == f x`. This function is useful for +avoiding parentheses. Consider the following code to create a text element: + + leftAligned (monospace (fromString "code")) + +This can also be written as: + + leftAligned <| monospace <| fromString "code" +-} +(<|) : (a -> b) -> a -> b +(<|) f x = + f x + + +infixr 9 << +infixl 9 >> +infixr 0 <| +infixl 0 |> + + +{-| Given a value, returns exactly the same value. This is called +[the identity function](http://en.wikipedia.org/wiki/Identity_function). +-} +identity : a -> a +identity x = + x + + +{-| Create a function that *always* returns the same value. Useful with +functions like `map`: + + List.map (always 0) [1,2,3,4,5] == [0,0,0,0,0] + + -- List.map (\_ -> 0) [1,2,3,4,5] == [0,0,0,0,0] + -- always = (\x _ -> x) +-} +always : a -> b -> a +always a _ = + a + + +{-| Flip the order of the first two arguments to a function. -} +flip : (a -> b -> c) -> (b -> a -> c) +flip f b a = + f a b + + +{-| Change how arguments are passed to a function. +This splits paired arguments into two separate arguments. +-} +curry : ((a,b) -> c) -> a -> b -> c +curry f a b = + f (a,b) + + +{-| Change how arguments are passed to a function. +This combines two arguments into a single pair. +-} +uncurry : (a -> b -> c) -> (a,b) -> c +uncurry f (a,b) = + f a b + + +{-| A value that can never happen! For context: + + - The boolean type `Bool` has two values: `True` and `False` + - The unit type `()` has one value: `()` + - The never type `Never` has no values! + +You may see it in the wild in `Html Never` which means this HTML will never +produce any messages. You would need to write an event handler like +`onClick ??? : Attribute Never` but how can we fill in the question marks?! +So there cannot be any event handlers on that HTML. + +You may also see this used with tasks that never fail, like `Task Never ()`. + +The `Never` type is useful for restricting *arguments* to a function. Maybe my +API can only accept HTML without event handlers, so I require `Html Never` and +users can give `Html msg` and everything will go fine. Generally speaking, you +do not want `Never` in your return types though. +-} +type Never = JustOneMore Never + + +{-| A function that can never be called. Seems extremely pointless, but it +*can* come in handy. Imagine you have some HTML that should never produce any +messages. And say you want to use it in some other HTML that *does* produce +messages. You could say: + + import Html exposing (..) + + embedHtml : Html Never -> Html msg + embedHtml staticStuff = + div [] + [ text "hello" + , Html.map never staticStuff + ] + +So the `never` function is basically telling the type system, make sure no one +ever calls me! +-} +never : Never -> a +never (JustOneMore nvr) = + never nvr diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Bitwise.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Bitwise.elm new file mode 100644 index 0000000..14c7a82 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Bitwise.elm @@ -0,0 +1,90 @@ +module Bitwise exposing + ( and, or, xor, complement + , shiftLeftBy, shiftRightBy, shiftRightZfBy + ) + +{-| Library for [bitwise operations](http://en.wikipedia.org/wiki/Bitwise_operation). + +# Basic Operations +@docs and, or, xor, complement + +# Bit Shifts +@docs shiftLeftBy, shiftRightBy, shiftRightZfBy +-} + +import Native.Bitwise + + +{-| Bitwise AND +-} +and : Int -> Int -> Int +and = + Native.Bitwise.and + + +{-| Bitwise OR +-} +or : Int -> Int -> Int +or = + Native.Bitwise.or + + +{-| Bitwise XOR +-} +xor : Int -> Int -> Int +xor = + Native.Bitwise.xor + + +{-| Flip each bit individually, often called bitwise NOT +-} +complement : Int -> Int +complement = + Native.Bitwise.complement + + +{-| Shift bits to the left by a given offset, filling new bits with zeros. +This can be used to multiply numbers by powers of two. + + shiftLeftBy 1 5 == 10 + shiftLeftBy 5 1 == 32 +-} +shiftLeftBy : Int -> Int -> Int +shiftLeftBy = + Native.Bitwise.shiftLeftBy + + +{-| Shift bits to the right by a given offset, filling new bits with +whatever is the topmost bit. This can be used to divide numbers by powers of two. + + shiftRightBy 1 32 == 16 + shiftRightBy 2 32 == 8 + shiftRightBy 1 -32 == -16 + +This is called an [arithmetic right shift][ars], often written (>>), and +sometimes called a sign-propagating right shift because it fills empty spots +with copies of the highest bit. + +[ars]: http://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift +-} +shiftRightBy : Int -> Int -> Int +shiftRightBy = + Native.Bitwise.shiftRightBy + + +{-| Shift bits to the right by a given offset, filling new bits with zeros. + + shiftRightZfBy 1 32 == 16 + shiftRightZfBy 2 32 == 8 + shiftRightZfBy 1 -32 == 2147483632 + +This is called an [logical right shift][lrs], often written (>>>), and +sometimes called a zero-fill right shift because it fills empty spots with +zeros. + +[lrs]: http://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift +-} +shiftRightZfBy : Int -> Int -> Int +shiftRightZfBy = + Native.Bitwise.shiftRightZfBy + diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Char.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Char.elm new file mode 100644 index 0000000..288f50b --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Char.elm @@ -0,0 +1,103 @@ +module Char exposing + ( isUpper, isLower, isDigit, isOctDigit, isHexDigit + , toUpper, toLower, toLocaleUpper, toLocaleLower + , KeyCode, toCode, fromCode + ) + +{-| Functions for working with characters. Character literals are enclosed in +`'a'` pair of single quotes. + +# Classification +@docs isUpper, isLower, isDigit, isOctDigit, isHexDigit + +# Conversion +@docs toUpper, toLower, toLocaleUpper, toLocaleLower + +# Key Codes +@docs KeyCode, toCode, fromCode + +-} + +import Native.Char +import Basics exposing ((&&), (||), (>=), (<=)) + + +isBetween : Char -> Char -> Char -> Bool +isBetween low high char = + let code = toCode char + in + (code >= toCode low) && (code <= toCode high) + + +{-| True for upper case ASCII letters. -} +isUpper : Char -> Bool +isUpper = + isBetween 'A' 'Z' + + +{-| True for lower case ASCII letters. -} +isLower : Char -> Bool +isLower = + isBetween 'a' 'z' + + +{-| True for ASCII digits `[0-9]`. -} +isDigit : Char -> Bool +isDigit = + isBetween '0' '9' + + +{-| True for ASCII octal digits `[0-7]`. -} +isOctDigit : Char -> Bool +isOctDigit = + isBetween '0' '7' + + +{-| True for ASCII hexadecimal digits `[0-9a-fA-F]`. -} +isHexDigit : Char -> Bool +isHexDigit char = + isDigit char || isBetween 'a' 'f' char || isBetween 'A' 'F' char + + +{-| Convert to upper case. -} +toUpper : Char -> Char +toUpper = + Native.Char.toUpper + + +{-| Convert to lower case. -} +toLower : Char -> Char +toLower = + Native.Char.toLower + + +{-| Convert to upper case, according to any locale-specific case mappings. -} +toLocaleUpper : Char -> Char +toLocaleUpper = + Native.Char.toLocaleUpper + + +{-| Convert to lower case, according to any locale-specific case mappings. -} +toLocaleLower : Char -> Char +toLocaleLower = + Native.Char.toLocaleLower + + +{-| Keyboard keys can be represented as integers. These are called *key codes*. +You can use [`toCode`](#toCode) and [`fromCode`](#fromCode) to convert between +key codes and characters. +-} +type alias KeyCode = Int + + +{-| Convert to key code. +-} +toCode : Char -> KeyCode +toCode = + Native.Char.toCode + + +{-| Convert from key code. -} +fromCode : KeyCode -> Char +fromCode = + Native.Char.fromCode diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Color.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Color.elm new file mode 100644 index 0000000..d150240 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Color.elm @@ -0,0 +1,456 @@ +module Color exposing + ( Color, rgb, rgba, hsl, hsla, greyscale, grayscale, complement + , Gradient, linear, radial + , toRgb, toHsl + , red, orange, yellow, green, blue, purple, brown + , lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple, lightBrown + , darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple, darkBrown + , white, lightGrey, grey, darkGrey, lightCharcoal, charcoal, darkCharcoal, black + , lightGray, gray, darkGray + ) + +{-| Library for working with colors. Includes +[RGB](https://en.wikipedia.org/wiki/RGB_color_model) and +[HSL](http://en.wikipedia.org/wiki/HSL_and_HSV) creation, gradients, and +built-in names. + +# Colors +@docs Color + +# Creation +@docs rgb, rgba, hsl, hsla, greyscale, grayscale, complement + +# Gradients +@docs Gradient, linear, radial + +# Extracting Colors +@docs toRgb, toHsl + +# Built-in Colors +These colors come from the [Tango +palette](http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines) +which provides aesthetically reasonable defaults for colors. Each color also +comes with a light and dark version. + +### Standard +@docs red, orange, yellow, green, blue, purple, brown + +### Light +@docs lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple, lightBrown + +### Dark +@docs darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple, darkBrown + +### Eight Shades of Grey +These colors are a compatible series of shades of grey, fitting nicely +with the Tango palette. +@docs white, lightGrey, grey, darkGrey, lightCharcoal, charcoal, darkCharcoal, black + +These are identical to the *grey* versions. It seems the spelling is regional, but +that has never helped me remember which one I should be writing. +@docs lightGray, gray, darkGray + +-} + +import Basics exposing (..) + + +{-| Representation of colors. +-} +type Color + = RGBA Int Int Int Float + | HSLA Float Float Float Float + + +{-| Create RGB colors with an alpha component for transparency. +The alpha component is specified with numbers between 0 and 1. -} +rgba : Int -> Int -> Int -> Float -> Color +rgba = + RGBA + + +{-| Create RGB colors from numbers between 0 and 255 inclusive. -} +rgb : Int -> Int -> Int -> Color +rgb r g b = + RGBA r g b 1 + + +{-| Create [HSL colors](http://en.wikipedia.org/wiki/HSL_and_HSV) +with an alpha component for transparency. +-} +hsla : Float -> Float -> Float -> Float -> Color +hsla hue saturation lightness alpha = + HSLA (hue - turns (toFloat (floor (hue / (2*pi))))) saturation lightness alpha + + +{-| Create [HSL colors](http://en.wikipedia.org/wiki/HSL_and_HSV). This gives +you access to colors more like a color wheel, where all hues are arranged in a +circle that you specify with standard Elm angles (radians). + + red = hsl (degrees 0) 1 0.5 + green = hsl (degrees 120) 1 0.5 + blue = hsl (degrees 240) 1 0.5 + + pastelRed = hsl (degrees 0) 0.7 0.7 + +To cycle through all colors, just cycle through degrees. The saturation level +is how vibrant the color is, like a dial between grey and bright colors. The +lightness level is a dial between white and black. +-} +hsl : Float -> Float -> Float -> Color +hsl hue saturation lightness = + hsla hue saturation lightness 1 + + +{-| Produce a gray based on the input. 0 is white, 1 is black. +-} +grayscale : Float -> Color +grayscale p = + HSLA 0 0 (1-p) 1 + + +{-| Produce a gray based on the input. 0 is white, 1 is black. +-} +greyscale : Float -> Color +greyscale p = + HSLA 0 0 (1-p) 1 + + +{-| Produce a “complementary color”. The two colors will +accent each other. This is the same as rotating the hue by 180°. +-} +complement : Color -> Color +complement color = + case color of + HSLA h s l a -> + hsla (h + degrees 180) s l a + + RGBA r g b a -> + let + (h,s,l) = rgbToHsl r g b + in + hsla (h + degrees 180) s l a + + +{-| Extract the components of a color in the HSL format. +-} +toHsl : Color -> { hue:Float, saturation:Float, lightness:Float, alpha:Float } +toHsl color = + case color of + HSLA h s l a -> + { hue=h, saturation=s, lightness=l, alpha=a } + + RGBA r g b a -> + let + (h,s,l) = rgbToHsl r g b + in + { hue=h, saturation=s, lightness=l, alpha=a } + + +{-| Extract the components of a color in the RGB format. +-} +toRgb : Color -> { red:Int, green:Int, blue:Int, alpha:Float } +toRgb color = + case color of + RGBA r g b a -> + { red = r, green = g, blue = b, alpha = a } + + HSLA h s l a -> + let + (r,g,b) = hslToRgb h s l + in + { red = round (255 * r) + , green = round (255 * g) + , blue = round (255 * b) + , alpha = a + } + + +fmod : Float -> Int -> Float +fmod f n = + let + integer = floor f + in + toFloat (integer % n) + f - toFloat integer + + +rgbToHsl : Int -> Int -> Int -> (Float,Float,Float) +rgbToHsl red green blue = + let + r = toFloat red / 255 + g = toFloat green / 255 + b = toFloat blue / 255 + + cMax = max (max r g) b + cMin = min (min r g) b + + c = cMax - cMin + + hue = + degrees 60 * + if cMax == r then + fmod ((g - b) / c) 6 + else if cMax == g then + ((b - r) / c) + 2 + else {- cMax == b -} + ((r - g) / c) + 4 + + lightness = + (cMax + cMin) / 2 + + saturation = + if lightness == 0 then + 0 + else + c / (1 - abs (2 * lightness - 1)) + in + (hue, saturation, lightness) + + +hslToRgb : Float -> Float -> Float -> (Float,Float,Float) +hslToRgb hue saturation lightness = + let + chroma = (1 - abs (2 * lightness - 1)) * saturation + normHue = hue / degrees 60 + + x = chroma * (1 - abs (fmod normHue 2 - 1)) + + (r,g,b) = + if normHue < 0 then (0, 0, 0) + else if normHue < 1 then (chroma, x, 0) + else if normHue < 2 then (x, chroma, 0) + else if normHue < 3 then (0, chroma, x) + else if normHue < 4 then (0, x, chroma) + else if normHue < 5 then (x, 0, chroma) + else if normHue < 6 then (chroma, 0, x) + else (0, 0, 0) + + m = lightness - chroma / 2 + in + (r + m, g + m, b + m) + + +--toV3 : Color -> V3 + +--toV4 : Color -> V4 + +{-| Abstract representation of a color gradient. +-} +type Gradient + = Linear (Float,Float) (Float,Float) (List (Float,Color)) + | Radial (Float,Float) Float (Float,Float) Float (List (Float,Color)) + + +{-| Create a linear gradient. Takes a start and end point and then a series of +“color stops” that indicate how to interpolate between the start and +end points. See [this example](http://elm-lang.org/examples/linear-gradient) for a +more visual explanation. +-} +linear : (Float, Float) -> (Float, Float) -> List (Float,Color) -> Gradient +linear = + Linear + + +{-| Create a radial gradient. First takes a start point and inner radius. Then +takes an end point and outer radius. It then takes a series of “color +stops” that indicate how to interpolate between the inner and outer +circles. See [this example](http://elm-lang.org/examples/radial-gradient) for a +more visual explanation. +-} +radial : (Float,Float) -> Float -> (Float,Float) -> Float -> List (Float,Color) -> Gradient +radial = + Radial + + +-- BUILT-IN COLORS + +{-|-} +lightRed : Color +lightRed = + RGBA 239 41 41 1 + + +{-|-} +red : Color +red = + RGBA 204 0 0 1 + + +{-|-} +darkRed : Color +darkRed = + RGBA 164 0 0 1 + + +{-|-} +lightOrange : Color +lightOrange = + RGBA 252 175 62 1 + + +{-|-} +orange : Color +orange = + RGBA 245 121 0 1 + + +{-|-} +darkOrange : Color +darkOrange = + RGBA 206 92 0 1 + + +{-|-} +lightYellow : Color +lightYellow = + RGBA 255 233 79 1 + + +{-|-} +yellow : Color +yellow = + RGBA 237 212 0 1 + + +{-|-} +darkYellow : Color +darkYellow = + RGBA 196 160 0 1 + + +{-|-} +lightGreen : Color +lightGreen = + RGBA 138 226 52 1 + + +{-|-} +green : Color +green = + RGBA 115 210 22 1 + + +{-|-} +darkGreen : Color +darkGreen = + RGBA 78 154 6 1 + + +{-|-} +lightBlue : Color +lightBlue = + RGBA 114 159 207 1 + + +{-|-} +blue : Color +blue = + RGBA 52 101 164 1 + + +{-|-} +darkBlue : Color +darkBlue = + RGBA 32 74 135 1 + + +{-|-} +lightPurple : Color +lightPurple = + RGBA 173 127 168 1 + + +{-|-} +purple : Color +purple = + RGBA 117 80 123 1 + + +{-|-} +darkPurple : Color +darkPurple = + RGBA 92 53 102 1 + + +{-|-} +lightBrown : Color +lightBrown = + RGBA 233 185 110 1 + + +{-|-} +brown : Color +brown = + RGBA 193 125 17 1 + + +{-|-} +darkBrown : Color +darkBrown = + RGBA 143 89 2 1 + + +{-|-} +black : Color +black = + RGBA 0 0 0 1 + + +{-|-} +white : Color +white = + RGBA 255 255 255 1 + + +{-|-} +lightGrey : Color +lightGrey = + RGBA 238 238 236 1 + + +{-|-} +grey : Color +grey = + RGBA 211 215 207 1 + + +{-|-} +darkGrey : Color +darkGrey = + RGBA 186 189 182 1 + + +{-|-} +lightGray : Color +lightGray = + RGBA 238 238 236 1 + + +{-|-} +gray : Color +gray = + RGBA 211 215 207 1 + + +{-|-} +darkGray : Color +darkGray = + RGBA 186 189 182 1 + + +{-|-} +lightCharcoal : Color +lightCharcoal = + RGBA 136 138 133 1 + + +{-|-} +charcoal : Color +charcoal = + RGBA 85 87 83 1 + + +{-|-} +darkCharcoal : Color +darkCharcoal = + RGBA 46 52 54 1 diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Date.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Date.elm new file mode 100644 index 0000000..0d62982 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Date.elm @@ -0,0 +1,150 @@ +module Date exposing + ( Date, fromString, toTime, fromTime + , year, month, Month(..) + , day, dayOfWeek, Day(..) + , hour, minute, second, millisecond + , now + ) + +{-| Library for working with dates. Email the mailing list if you encounter +issues with internationalization or locale formatting. + +# Dates +@docs Date, now + +# Conversions +@docs fromString, toTime, fromTime + +# Extractions +@docs year, month, Month, day, dayOfWeek, Day, hour, minute, second, millisecond + +-} + +import Native.Date +import Task exposing (Task) +import Time exposing (Time) +import Result exposing (Result) + + + +-- DATES + + +{-| Representation of a date. +-} +type Date = Date + + +{-| Get the `Date` at the moment when this task is run. +-} +now : Task x Date +now = + Task.map fromTime Time.now + + + +-- CONVERSIONS AND EXTRACTIONS + + +{-| Represents the days of the week. +-} +type Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun + + +{-| Represents the month of the year. +-} +type Month + = Jan | Feb | Mar | Apr + | May | Jun | Jul | Aug + | Sep | Oct | Nov | Dec + + +{-| Attempt to read a date from a string. +-} +fromString : String -> Result String Date +fromString = + Native.Date.fromString + + +{-| Convert a `Date` to a time in milliseconds. + +A time is the number of milliseconds since +[the Unix epoch](http://en.wikipedia.org/wiki/Unix_time). +-} +toTime : Date -> Time +toTime = + Native.Date.toTime + + +{-| Convert a time in milliseconds into a `Date`. + +A time is the number of milliseconds since +[the Unix epoch](http://en.wikipedia.org/wiki/Unix_time). +-} +fromTime : Time -> Date +fromTime = + Native.Date.fromTime + + +{-| Extract the year of a given date. Given the date 23 June 1990 at 11:45AM +this returns the integer `1990`. +-} +year : Date -> Int +year = + Native.Date.year + + +{-| Extract the month of a given date. Given the date 23 June 1990 at 11:45AM +this returns the month `Jun` as defined below. +-} +month : Date -> Month +month = + Native.Date.month + + +{-| Extract the day of a given date. Given the date 23 June 1990 at 11:45AM +this returns the integer `23`. +-} +day : Date -> Int +day = + Native.Date.day + + +{-| Extract the day of the week for a given date. Given the date 23 June +1990 at 11:45AM this returns the day `Sat` as defined below. +-} +dayOfWeek : Date -> Day +dayOfWeek = + Native.Date.dayOfWeek + + +{-| Extract the hour of a given date. Given the date 23 June 1990 at 11:45AM +this returns the integer `11`. +-} +hour : Date -> Int +hour = + Native.Date.hour + + +{-| Extract the minute of a given date. Given the date 23 June 1990 at 11:45AM +this returns the integer `45`. +-} +minute : Date -> Int +minute = + Native.Date.minute + + +{-| Extract the second of a given date. Given the date 23 June 1990 at 11:45AM +this returns the integer `0`. +-} +second : Date -> Int +second = + Native.Date.second + + +{-| Extract the millisecond of a given date. Given the date 23 June 1990 at 11:45:30.123AM +this returns the integer `123`. +-} +millisecond : Date -> Int +millisecond = + Native.Date.millisecond diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Debug.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Debug.elm new file mode 100644 index 0000000..49668f5 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Debug.elm @@ -0,0 +1,62 @@ +module Debug exposing + ( log + , crash + ) + +{-| This library is for investigating bugs or performance problems. It should +*not* be used in production code. + +# Debugging +@docs log, crash +-} + +import Native.Debug + + +{-| Log a tagged value on the developer console, and then return the value. + + 1 + log "number" 1 -- equals 2, logs "number: 1" + length (log "start" []) -- equals 0, logs "start: []" + +Notice that `log` is not a pure function! It should *only* be used for +investigating bugs or performance problems. +-} +log : String -> a -> a +log = + Native.Debug.log + + +{-| Crash the program with an error message. This is an uncatchable error, +intended for code that is soon-to-be-implemented. For example, if you are +working with a large ADT and have partially completed a case expression, it may +make sense to do this: + + type Entity = Ship | Fish | Captain | Seagull + + drawEntity entity = + case entity of + Ship -> + ... + + Fish -> + ... + + _ -> + Debug.crash "TODO" + +The Elm compiler recognizes each `Debug.crash` and when you run into it at +runtime, the error will point to the corresponding module name and line number. +For `case` expressions that ends with a wildcard pattern and a crash, it will +also show the value that snuck through. In our example, that'd be `Captain` or +`Seagull`. + +**Use this if** you want to do some testing while you are partway through +writing a function. + +**Do not use this if** you want to do some typical try-catch exception handling. +Use the [`Maybe`](Maybe) or [`Result`](Result) libraries instead. +-} +crash : String -> a +crash = + Native.Debug.crash + diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Dict.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Dict.elm new file mode 100644 index 0000000..0bb9501 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Dict.elm @@ -0,0 +1,661 @@ +module Dict exposing + ( Dict + , empty, singleton, insert, update + , isEmpty, get, remove, member, size + , filter + , partition + , foldl, foldr, map + , union, intersect, diff, merge + , keys, values + , toList, fromList + ) + +{-| A dictionary mapping unique keys to values. The keys can be any comparable +type. This includes `Int`, `Float`, `Time`, `Char`, `String`, and tuples or +lists of comparable types. + +Insert, remove, and query operations all take *O(log n)* time. + +# Dictionaries +@docs Dict + +# Build +@docs empty, singleton, insert, update, remove + +# Query +@docs isEmpty, member, get, size + +# Lists +@docs keys, values, toList, fromList + +# Transform +@docs map, foldl, foldr, filter, partition + +# Combine +@docs union, intersect, diff, merge + +-} + + +import Basics exposing (..) +import Maybe exposing (..) +import List exposing (..) +import Native.Debug +import String + + + +-- DICTIONARIES + + +-- BBlack and NBlack should only be used during the deletion +-- algorithm. Any other occurrence is a bug and should fail an assert. +type NColor + = Red + | Black + | BBlack -- Double Black, counts as 2 blacks for the invariant + | NBlack -- Negative Black, counts as -1 blacks for the invariant + + +type LeafColor + = LBlack + | LBBlack -- Double Black, counts as 2 + + +{-| A dictionary of keys and values. So a `(Dict String User)` is a dictionary +that lets you look up a `String` (such as user names) and find the associated +`User`. +-} +type Dict k v + = RBNode_elm_builtin NColor k v (Dict k v) (Dict k v) + | RBEmpty_elm_builtin LeafColor + + +{-| Create an empty dictionary. -} +empty : Dict k v +empty = + RBEmpty_elm_builtin LBlack + + +maxWithDefault : k -> v -> Dict k v -> (k, v) +maxWithDefault k v r = + case r of + RBEmpty_elm_builtin _ -> + (k, v) + + RBNode_elm_builtin _ kr vr _ rr -> + maxWithDefault kr vr rr + + +{-| Get the value associated with a key. If the key is not found, return +`Nothing`. This is useful when you are not sure if a key will be in the +dictionary. + + animals = fromList [ ("Tom", Cat), ("Jerry", Mouse) ] + + get "Tom" animals == Just Cat + get "Jerry" animals == Just Mouse + get "Spike" animals == Nothing + +-} +get : comparable -> Dict comparable v -> Maybe v +get targetKey dict = + case dict of + RBEmpty_elm_builtin _ -> + Nothing + + RBNode_elm_builtin _ key value left right -> + case compare targetKey key of + LT -> + get targetKey left + + EQ -> + Just value + + GT -> + get targetKey right + + +{-| Determine if a key is in a dictionary. -} +member : comparable -> Dict comparable v -> Bool +member key dict = + case get key dict of + Just _ -> + True + + Nothing -> + False + + +{-| Determine the number of key-value pairs in the dictionary. -} +size : Dict k v -> Int +size dict = + sizeHelp 0 dict + + +sizeHelp : Int -> Dict k v -> Int +sizeHelp n dict = + case dict of + RBEmpty_elm_builtin _ -> + n + + RBNode_elm_builtin _ _ _ left right -> + sizeHelp (sizeHelp (n+1) right) left + + +{-| Determine if a dictionary is empty. + + isEmpty empty == True +-} +isEmpty : Dict k v -> Bool +isEmpty dict = + dict == empty + + +{- The actual pattern match here is somewhat lax. If it is given invalid input, +it will do the wrong thing. The expected behavior is: + + red node => black node + black node => same + bblack node => xxx + nblack node => xxx + + black leaf => same + bblack leaf => xxx +-} +ensureBlackRoot : Dict k v -> Dict k v +ensureBlackRoot dict = + case dict of + RBNode_elm_builtin Red key value left right -> + RBNode_elm_builtin Black key value left right + + _ -> + dict + + +{-| Insert a key-value pair into a dictionary. Replaces value when there is +a collision. -} +insert : comparable -> v -> Dict comparable v -> Dict comparable v +insert key value dict = + update key (always (Just value)) dict + + +{-| Remove a key-value pair from a dictionary. If the key is not found, +no changes are made. -} +remove : comparable -> Dict comparable v -> Dict comparable v +remove key dict = + update key (always Nothing) dict + + +type Flag = Insert | Remove | Same + + +{-| Update the value of a dictionary for a specific key with a given function. -} +update : comparable -> (Maybe v -> Maybe v) -> Dict comparable v -> Dict comparable v +update k alter dict = + let + up dict = + case dict of + -- expecting only black nodes, never double black nodes here + RBEmpty_elm_builtin _ -> + case alter Nothing of + Nothing -> + (Same, empty) + + Just v -> + (Insert, RBNode_elm_builtin Red k v empty empty) + + RBNode_elm_builtin clr key value left right -> + case compare k key of + EQ -> + case alter (Just value) of + Nothing -> + (Remove, rem clr left right) + + Just newValue -> + (Same, RBNode_elm_builtin clr key newValue left right) + + LT -> + let (flag, newLeft) = up left in + case flag of + Same -> + (Same, RBNode_elm_builtin clr key value newLeft right) + + Insert -> + (Insert, balance clr key value newLeft right) + + Remove -> + (Remove, bubble clr key value newLeft right) + + GT -> + let (flag, newRight) = up right in + case flag of + Same -> + (Same, RBNode_elm_builtin clr key value left newRight) + + Insert -> + (Insert, balance clr key value left newRight) + + Remove -> + (Remove, bubble clr key value left newRight) + + (flag, updatedDict) = + up dict + in + case flag of + Same -> + updatedDict + + Insert -> + ensureBlackRoot updatedDict + + Remove -> + blacken updatedDict + + +{-| Create a dictionary with one key-value pair. -} +singleton : comparable -> v -> Dict comparable v +singleton key value = + insert key value empty + + + +-- HELPERS + + +isBBlack : Dict k v -> Bool +isBBlack dict = + case dict of + RBNode_elm_builtin BBlack _ _ _ _ -> + True + + RBEmpty_elm_builtin LBBlack -> + True + + _ -> + False + + +moreBlack : NColor -> NColor +moreBlack color = + case color of + Black -> + BBlack + + Red -> + Black + + NBlack -> + Red + + BBlack -> + Native.Debug.crash "Can't make a double black node more black!" + + +lessBlack : NColor -> NColor +lessBlack color = + case color of + BBlack -> + Black + + Black -> + Red + + Red -> + NBlack + + NBlack -> + Native.Debug.crash "Can't make a negative black node less black!" + + +{- The actual pattern match here is somewhat lax. If it is given invalid input, +it will do the wrong thing. The expected behavior is: + + node => less black node + + bblack leaf => black leaf + black leaf => xxx +-} +lessBlackTree : Dict k v -> Dict k v +lessBlackTree dict = + case dict of + RBNode_elm_builtin c k v l r -> + RBNode_elm_builtin (lessBlack c) k v l r + + RBEmpty_elm_builtin _ -> + RBEmpty_elm_builtin LBlack + + +reportRemBug : String -> NColor -> String -> String -> a +reportRemBug msg c lgot rgot = + Native.Debug.crash <| + String.concat + [ "Internal red-black tree invariant violated, expected " + , msg, " and got ", toString c, "/", lgot, "/", rgot + , "\nPlease report this bug to " + ] + + +-- Remove the top node from the tree, may leave behind BBlacks +rem : NColor -> Dict k v -> Dict k v -> Dict k v +rem color left right = + case (left, right) of + (RBEmpty_elm_builtin _, RBEmpty_elm_builtin _) -> + case color of + Red -> + RBEmpty_elm_builtin LBlack + + Black -> + RBEmpty_elm_builtin LBBlack + + _ -> + Native.Debug.crash "cannot have bblack or nblack nodes at this point" + + (RBEmpty_elm_builtin cl, RBNode_elm_builtin cr k v l r) -> + case (color, cl, cr) of + (Black, LBlack, Red) -> + RBNode_elm_builtin Black k v l r + + _ -> + reportRemBug "Black/LBlack/Red" color (toString cl) (toString cr) + + (RBNode_elm_builtin cl k v l r, RBEmpty_elm_builtin cr) -> + case (color, cl, cr) of + (Black, Red, LBlack) -> + RBNode_elm_builtin Black k v l r + + _ -> + reportRemBug "Black/Red/LBlack" color (toString cl) (toString cr) + + -- l and r are both RBNodes + (RBNode_elm_builtin cl kl vl ll rl, RBNode_elm_builtin _ _ _ _ _) -> + let + (k, v) = + maxWithDefault kl vl rl + + newLeft = + removeMax cl kl vl ll rl + in + bubble color k v newLeft right + + +-- Kills a BBlack or moves it upward, may leave behind NBlack +bubble : NColor -> k -> v -> Dict k v -> Dict k v -> Dict k v +bubble c k v l r = + if isBBlack l || isBBlack r then + balance (moreBlack c) k v (lessBlackTree l) (lessBlackTree r) + + else + RBNode_elm_builtin c k v l r + + +-- Removes rightmost node, may leave root as BBlack +removeMax : NColor -> k -> v -> Dict k v -> Dict k v -> Dict k v +removeMax c k v l r = + case r of + RBEmpty_elm_builtin _ -> + rem c l r + + RBNode_elm_builtin cr kr vr lr rr -> + bubble c k v l (removeMax cr kr vr lr rr) + + +-- generalized tree balancing act +balance : NColor -> k -> v -> Dict k v -> Dict k v -> Dict k v +balance c k v l r = + let + tree = + RBNode_elm_builtin c k v l r + in + if blackish tree then + balanceHelp tree + + else + tree + + +blackish : Dict k v -> Bool +blackish t = + case t of + RBNode_elm_builtin c _ _ _ _ -> + c == Black || c == BBlack + + RBEmpty_elm_builtin _ -> + True + + +balanceHelp : Dict k v -> Dict k v +balanceHelp tree = + case tree of + -- double red: left, left + RBNode_elm_builtin col zk zv (RBNode_elm_builtin Red yk yv (RBNode_elm_builtin Red xk xv a b) c) d -> + balancedTree col xk xv yk yv zk zv a b c d + + -- double red: left, right + RBNode_elm_builtin col zk zv (RBNode_elm_builtin Red xk xv a (RBNode_elm_builtin Red yk yv b c)) d -> + balancedTree col xk xv yk yv zk zv a b c d + + -- double red: right, left + RBNode_elm_builtin col xk xv a (RBNode_elm_builtin Red zk zv (RBNode_elm_builtin Red yk yv b c) d) -> + balancedTree col xk xv yk yv zk zv a b c d + + -- double red: right, right + RBNode_elm_builtin col xk xv a (RBNode_elm_builtin Red yk yv b (RBNode_elm_builtin Red zk zv c d)) -> + balancedTree col xk xv yk yv zk zv a b c d + + -- handle double blacks + RBNode_elm_builtin BBlack xk xv a (RBNode_elm_builtin NBlack zk zv (RBNode_elm_builtin Black yk yv b c) (RBNode_elm_builtin Black _ _ _ _ as d)) -> + RBNode_elm_builtin Black yk yv (RBNode_elm_builtin Black xk xv a b) (balance Black zk zv c (redden d)) + + RBNode_elm_builtin BBlack zk zv (RBNode_elm_builtin NBlack xk xv (RBNode_elm_builtin Black _ _ _ _ as a) (RBNode_elm_builtin Black yk yv b c)) d -> + RBNode_elm_builtin Black yk yv (balance Black xk xv (redden a) b) (RBNode_elm_builtin Black zk zv c d) + + _ -> + tree + + +balancedTree : NColor -> k -> v -> k -> v -> k -> v -> Dict k v -> Dict k v -> Dict k v -> Dict k v -> Dict k v +balancedTree col xk xv yk yv zk zv a b c d = + RBNode_elm_builtin + (lessBlack col) + yk + yv + (RBNode_elm_builtin Black xk xv a b) + (RBNode_elm_builtin Black zk zv c d) + + +-- make the top node black +blacken : Dict k v -> Dict k v +blacken t = + case t of + RBEmpty_elm_builtin _ -> + RBEmpty_elm_builtin LBlack + + RBNode_elm_builtin _ k v l r -> + RBNode_elm_builtin Black k v l r + + +-- make the top node red +redden : Dict k v -> Dict k v +redden t = + case t of + RBEmpty_elm_builtin _ -> + Native.Debug.crash "can't make a Leaf red" + + RBNode_elm_builtin _ k v l r -> + RBNode_elm_builtin Red k v l r + + + +-- COMBINE + + +{-| Combine two dictionaries. If there is a collision, preference is given +to the first dictionary. +-} +union : Dict comparable v -> Dict comparable v -> Dict comparable v +union t1 t2 = + foldl insert t2 t1 + + +{-| Keep a key-value pair when its key appears in the second dictionary. +Preference is given to values in the first dictionary. +-} +intersect : Dict comparable v -> Dict comparable v -> Dict comparable v +intersect t1 t2 = + filter (\k _ -> member k t2) t1 + + +{-| Keep a key-value pair when its key does not appear in the second dictionary. +-} +diff : Dict comparable v -> Dict comparable v -> Dict comparable v +diff t1 t2 = + foldl (\k v t -> remove k t) t1 t2 + + +{-| The most general way of combining two dictionaries. You provide three +accumulators for when a given key appears: + + 1. Only in the left dictionary. + 2. In both dictionaries. + 3. Only in the right dictionary. + +You then traverse all the keys from lowest to highest, building up whatever +you want. +-} +merge + : (comparable -> a -> result -> result) + -> (comparable -> a -> b -> result -> result) + -> (comparable -> b -> result -> result) + -> Dict comparable a + -> Dict comparable b + -> result + -> result +merge leftStep bothStep rightStep leftDict rightDict initialResult = + let + stepState rKey rValue (list, result) = + case list of + [] -> + (list, rightStep rKey rValue result) + + (lKey, lValue) :: rest -> + if lKey < rKey then + stepState rKey rValue (rest, leftStep lKey lValue result) + + else if lKey > rKey then + (list, rightStep rKey rValue result) + + else + (rest, bothStep lKey lValue rValue result) + + (leftovers, intermediateResult) = + foldl stepState (toList leftDict, initialResult) rightDict + in + List.foldl (\(k,v) result -> leftStep k v result) intermediateResult leftovers + + + +-- TRANSFORM + + +{-| Apply a function to all values in a dictionary. +-} +map : (comparable -> a -> b) -> Dict comparable a -> Dict comparable b +map f dict = + case dict of + RBEmpty_elm_builtin _ -> + RBEmpty_elm_builtin LBlack + + RBNode_elm_builtin clr key value left right -> + RBNode_elm_builtin clr key (f key value) (map f left) (map f right) + + +{-| Fold over the key-value pairs in a dictionary, in order from lowest +key to highest key. +-} +foldl : (comparable -> v -> b -> b) -> b -> Dict comparable v -> b +foldl f acc dict = + case dict of + RBEmpty_elm_builtin _ -> + acc + + RBNode_elm_builtin _ key value left right -> + foldl f (f key value (foldl f acc left)) right + + +{-| Fold over the key-value pairs in a dictionary, in order from highest +key to lowest key. +-} +foldr : (comparable -> v -> b -> b) -> b -> Dict comparable v -> b +foldr f acc t = + case t of + RBEmpty_elm_builtin _ -> + acc + + RBNode_elm_builtin _ key value left right -> + foldr f (f key value (foldr f acc right)) left + + +{-| Keep a key-value pair when it satisfies a predicate. -} +filter : (comparable -> v -> Bool) -> Dict comparable v -> Dict comparable v +filter predicate dictionary = + let + add key value dict = + if predicate key value then + insert key value dict + + else + dict + in + foldl add empty dictionary + + +{-| Partition a dictionary according to a predicate. The first dictionary +contains all key-value pairs which satisfy the predicate, and the second +contains the rest. +-} +partition : (comparable -> v -> Bool) -> Dict comparable v -> (Dict comparable v, Dict comparable v) +partition predicate dict = + let + add key value (t1, t2) = + if predicate key value then + (insert key value t1, t2) + + else + (t1, insert key value t2) + in + foldl add (empty, empty) dict + + + +-- LISTS + + +{-| Get all of the keys in a dictionary, sorted from lowest to highest. + + keys (fromList [(0,"Alice"),(1,"Bob")]) == [0,1] +-} +keys : Dict comparable v -> List comparable +keys dict = + foldr (\key value keyList -> key :: keyList) [] dict + + +{-| Get all of the values in a dictionary, in the order of their keys. + + values (fromList [(0,"Alice"),(1,"Bob")]) == ["Alice", "Bob"] +-} +values : Dict comparable v -> List v +values dict = + foldr (\key value valueList -> value :: valueList) [] dict + + +{-| Convert a dictionary into an association list of key-value pairs, sorted by keys. -} +toList : Dict comparable v -> List (comparable,v) +toList dict = + foldr (\key value list -> (key,value) :: list) [] dict + + +{-| Convert an association list into a dictionary. -} +fromList : List (comparable,v) -> Dict comparable v +fromList assocs = + List.foldl (\(key,value) dict -> insert key value dict) empty assocs diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Json/Decode.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Json/Decode.elm new file mode 100644 index 0000000..0fc853d --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Json/Decode.elm @@ -0,0 +1,520 @@ +module Json.Decode exposing + ( Decoder, string, bool, int, float + , nullable, list, array, dict, keyValuePairs + , field, at, index + , maybe, oneOf + , decodeString, decodeValue, Value + , map, map2, map3, map4, map5, map6, map7, map8 + , lazy, value, null, succeed, fail, andThen + ) + +{-| Turn JSON values into Elm values. Definitely check out this [intro to +JSON decoders][guide] to get a feel for how this library works! + +[guide]: https://guide.elm-lang.org/interop/json.html + +# Primitives +@docs Decoder, string, bool, int, float + +# Data Structures +@docs nullable, list, array, dict, keyValuePairs + +# Object Primitives +@docs field, at, index + +# Inconsistent Structure +@docs maybe, oneOf + +# Run Decoders +@docs decodeString, decodeValue, Value + +# Mapping + +**Note:** If you run out of map functions, take a look at [elm-decode-pipeline][pipe] +which makes it easier to handle large objects, but produces lower quality type +errors. + +[pipe]: http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest + +@docs map, map2, map3, map4, map5, map6, map7, map8 + +# Fancy Decoding +@docs lazy, value, null, succeed, fail, andThen +-} + + +import Array exposing (Array) +import Dict exposing (Dict) +import Json.Encode as JsEncode +import List +import Maybe exposing (Maybe(..)) +import Result exposing (Result(..)) +import Native.Json + + + +-- PRIMITIVES + + +{-| A value that knows how to decode JSON values. +-} +type Decoder a = Decoder + + +{-| Decode a JSON string into an Elm `String`. + + decodeString string "true" == Err ... + decodeString string "42" == Err ... + decodeString string "3.14" == Err ... + decodeString string "\"hello\"" == Ok "hello" + decodeString string "{ \"hello\": 42 }" == Err ... +-} +string : Decoder String +string = + Native.Json.decodePrimitive "string" + + +{-| Decode a JSON boolean into an Elm `Bool`. + + decodeString bool "true" == Ok True + decodeString bool "42" == Err ... + decodeString bool "3.14" == Err ... + decodeString bool "\"hello\"" == Err ... + decodeString bool "{ \"hello\": 42 }" == Err ... +-} +bool : Decoder Bool +bool = + Native.Json.decodePrimitive "bool" + + +{-| Decode a JSON number into an Elm `Int`. + + decodeString int "true" == Err ... + decodeString int "42" == Ok 42 + decodeString int "3.14" == Err ... + decodeString int "\"hello\"" == Err ... + decodeString int "{ \"hello\": 42 }" == Err ... +-} +int : Decoder Int +int = + Native.Json.decodePrimitive "int" + + +{-| Decode a JSON number into an Elm `Float`. + + decodeString float "true" == Err .. + decodeString float "42" == Ok 42 + decodeString float "3.14" == Ok 3.14 + decodeString float "\"hello\"" == Err ... + decodeString float "{ \"hello\": 42 }" == Err ... +-} +float : Decoder Float +float = + Native.Json.decodePrimitive "float" + + + +-- DATA STRUCTURES + + +{-| Decode a nullable JSON value into an Elm value. + + decodeString (nullable int) "13" == Ok (Just 13) + decodeString (nullable int) "42" == Ok (Just 42) + decodeString (nullable int) "null" == Ok Nothing + decodeString (nullable int) "true" == Err .. +-} +nullable : Decoder a -> Decoder (Maybe a) +nullable decoder = + oneOf + [ null Nothing + , map Just decoder + ] + + +{-| Decode a JSON array into an Elm `List`. + + decodeString (list int) "[1,2,3]" == Ok [1,2,3] + decodeString (list bool) "[true,false]" == Ok [True,False] +-} +list : Decoder a -> Decoder (List a) +list decoder = + Native.Json.decodeContainer "list" decoder + + +{-| Decode a JSON array into an Elm `Array`. + + decodeString (array int) "[1,2,3]" == Ok (Array.fromList [1,2,3]) + decodeString (array bool) "[true,false]" == Ok (Array.fromList [True,False]) +-} +array : Decoder a -> Decoder (Array a) +array decoder = + Native.Json.decodeContainer "array" decoder + + +{-| Decode a JSON object into an Elm `Dict`. + + decodeString (dict int) "{ \"alice\": 42, \"bob\": 99 }" + == Dict.fromList [("alice", 42), ("bob", 99)] +-} +dict : Decoder a -> Decoder (Dict String a) +dict decoder = + map Dict.fromList (keyValuePairs decoder) + + +{-| Decode a JSON object into an Elm `List` of pairs. + + decodeString (keyValuePairs int) "{ \"alice\": 42, \"bob\": 99 }" + == [("alice", 42), ("bob", 99)] +-} +keyValuePairs : Decoder a -> Decoder (List (String, a)) +keyValuePairs = + Native.Json.decodeKeyValuePairs + + + +-- OBJECT PRIMITIVES + + +{-| Decode a JSON object, requiring a particular field. + + decodeString (field "x" int) "{ \"x\": 3 }" == Ok 3 + decodeString (field "x" int) "{ \"x\": 3, \"y\": 4 }" == Ok 3 + decodeString (field "x" int) "{ \"x\": true }" == Err ... + decodeString (field "x" int) "{ \"y\": 4 }" == Err ... + + decodeString (field "name" string) "{ \"name\": \"tom\" }" == Ok "tom" + +The object *can* have other fields. Lots of them! The only thing this decoder +cares about is if `x` is present and that the value there is an `Int`. + +Check out [`map2`](#map2) to see how to decode multiple fields! +-} +field : String -> Decoder a -> Decoder a +field = + Native.Json.decodeField + + +{-| Decode a nested JSON object, requiring certain fields. + + json = """{ "person": { "name": "tom", "age": 42 } }""" + + decodeString (at ["person", "name"] string) json == Ok "tom" + decodeString (at ["person", "age" ] int ) json == Ok "42 + +This is really just a shorthand for saying things like: + + field "person" (field "name" string) == at ["person","name"] string +-} +at : List String -> Decoder a -> Decoder a +at fields decoder = + List.foldr field decoder fields + + +{-| Decode a JSON array, requiring a particular index. + + json = """[ "alice", "bob", "chuck" ]""" + + decodeString (index 0 string) json == Ok "alice" + decodeString (index 1 string) json == Ok "bob" + decodeString (index 2 string) json == Ok "chuck" + decodeString (index 3 string) json == Err ... +-} +index : Int -> Decoder a -> Decoder a +index = + Native.Json.decodeIndex + + + +-- WEIRD STRUCTURE + + +{-| Helpful for dealing with optional fields. Here are a few slightly different +examples: + + json = """{ "name": "tom", "age": 42 }""" + + decodeString (maybe (field "age" int )) json == Ok (Just 42) + decodeString (maybe (field "name" int )) json == Ok Nothing + decodeString (maybe (field "height" float)) json == Ok Nothing + + decodeString (field "age" (maybe int )) json == Ok (Just 42) + decodeString (field "name" (maybe int )) json == Ok Nothing + decodeString (field "height" (maybe float)) json == Err ... + +Notice the last example! It is saying we *must* have a field named `height` and +the content *may* be a float. There is no `height` field, so the decoder fails. + +Point is, `maybe` will make exactly what it contains conditional. For optional +fields, this means you probably want it *outside* a use of `field` or `at`. +-} +maybe : Decoder a -> Decoder (Maybe a) +maybe decoder = + Native.Json.decodeContainer "maybe" decoder + + +{-| Try a bunch of different decoders. This can be useful if the JSON may come +in a couple different formats. For example, say you want to read an array of +numbers, but some of them are `null`. + + import String + + badInt : Decoder Int + badInt = + oneOf [ int, null 0 ] + + -- decodeString (list badInt) "[1,2,null,4]" == Ok [1,2,0,4] + +Why would someone generate JSON like this? Questions like this are not good +for your health. The point is that you can use `oneOf` to handle situations +like this! + +You could also use `oneOf` to help version your data. Try the latest format, +then a few older ones that you still support. You could use `andThen` to be +even more particular if you wanted. +-} +oneOf : List (Decoder a) -> Decoder a +oneOf = + Native.Json.oneOf + + + +-- MAPPING + + +{-| Transform a decoder. Maybe you just want to know the length of a string: + + import String + + stringLength : Decoder Int + stringLength = + map String.length string + +It is often helpful to use `map` with `oneOf`, like when defining `nullable`: + + nullable : Decoder a -> Decoder (Maybe a) + nullable decoder = + oneOf + [ null Nothing + , map Just decoder + ] +-} +map : (a -> value) -> Decoder a -> Decoder value +map = + Native.Json.map1 + + +{-| Try two decoders and then combine the result. We can use this to decode +objects with many fields: + + type alias Point = { x : Float, y : Float } + + point : Decoder Point + point = + map2 Point + (field "x" float) + (field "y" float) + + -- decodeString point """{ "x": 3, "y": 4 }""" == Ok { x = 3, y = 4 } + +It tries each individual decoder and puts the result together with the `Point` +constructor. +-} +map2 : (a -> b -> value) -> Decoder a -> Decoder b -> Decoder value +map2 = + Native.Json.map2 + + +{-| Try three decoders and then combine the result. We can use this to decode +objects with many fields: + + type alias Person = { name : String, age : Int, height : Float } + + person : Decoder Person + person = + map3 Person + (at ["name"] string) + (at ["info","age"] int) + (at ["info","height"] float) + + -- json = """{ "name": "tom", "info": { "age": 42, "height": 1.8 } }""" + -- decodeString person json == Ok { name = "tom", age = 42, height = 1.8 } + +Like `map2` it tries each decoder in order and then give the results to the +`Person` constructor. That can be any function though! +-} +map3 : (a -> b -> c -> value) -> Decoder a -> Decoder b -> Decoder c -> Decoder value +map3 = + Native.Json.map3 + + +{-|-} +map4 : (a -> b -> c -> d -> value) -> Decoder a -> Decoder b -> Decoder c -> Decoder d -> Decoder value +map4 = + Native.Json.map4 + + +{-|-} +map5 : (a -> b -> c -> d -> e -> value) -> Decoder a -> Decoder b -> Decoder c -> Decoder d -> Decoder e -> Decoder value +map5 = + Native.Json.map5 + + +{-|-} +map6 : (a -> b -> c -> d -> e -> f -> value) -> Decoder a -> Decoder b -> Decoder c -> Decoder d -> Decoder e -> Decoder f -> Decoder value +map6 = + Native.Json.map6 + + +{-|-} +map7 : (a -> b -> c -> d -> e -> f -> g -> value) -> Decoder a -> Decoder b -> Decoder c -> Decoder d -> Decoder e -> Decoder f -> Decoder g -> Decoder value +map7 = + Native.Json.map7 + + +{-|-} +map8 : (a -> b -> c -> d -> e -> f -> g -> h -> value) -> Decoder a -> Decoder b -> Decoder c -> Decoder d -> Decoder e -> Decoder f -> Decoder g -> Decoder h -> Decoder value +map8 = + Native.Json.map8 + + + +-- RUN DECODERS + + +{-| Parse the given string into a JSON value and then run the `Decoder` on it. +This will fail if the string is not well-formed JSON or if the `Decoder` +fails for some reason. + + decodeString int "4" == Ok 4 + decodeString int "1 + 2" == Err ... +-} +decodeString : Decoder a -> String -> Result String a +decodeString = + Native.Json.runOnString + + +{-| Run a `Decoder` on some JSON `Value`. You can send these JSON values +through ports, so that is probably the main time you would use this function. +-} +decodeValue : Decoder a -> Value -> Result String a +decodeValue = + Native.Json.run + + +{-| A JSON value. +-} +type alias Value = JsEncode.Value + + + +-- FANCY PRIMITIVES + + +{-| Ignore the JSON and produce a certain Elm value. + + decodeString (succeed 42) "true" == Ok 42 + decodeString (succeed 42) "[1,2,3]" == Ok 42 + decodeString (succeed 42) "hello" == Err ... -- this is not a valid JSON string + +This is handy when used with `oneOf` or `andThen`. +-} +succeed : a -> Decoder a +succeed = + Native.Json.succeed + + +{-| Ignore the JSON and make the decoder fail. This is handy when used with +`oneOf` or `andThen` where you want to give a custom error message in some +case. + +See the [`andThen`](#andThen) docs for an example. +-} +fail : String -> Decoder a +fail = + Native.Json.fail + + +{-| Create decoders that depend on previous results. If you are creating +versioned data, you might do something like this: + + info : Decoder Info + info = + field "version" int + |> andThen infoHelp + + infoHelp : Int -> Decoder Info + infoHelp version = + case version of + 4 -> + infoDecoder4 + + 3 -> + infoDecoder3 + + _ -> + fail <| + "Trying to decode info, but version " + ++ toString version ++ " is not supported." + + -- infoDecoder4 : Decoder Info + -- infoDecoder3 : Decoder Info +-} +andThen : (a -> Decoder b) -> Decoder a -> Decoder b +andThen = + Native.Json.andThen + + +{-| Sometimes you have JSON with recursive structure, like nested comments. +You can use `lazy` to make sure your decoder unrolls lazily. + + type alias Comment = + { message : String + , responses : Responses + } + + type Responses = Responses (List Comment) + + comment : Decoder Comment + comment = + map2 Comment + (field "message" string) + (field "responses" (map Responses (list (lazy (\_ -> comment))))) + +If we had said `list comment` instead, we would start expanding the value +infinitely. What is a `comment`? It is a decoder for objects where the +`responses` field contains comments. What is a `comment` though? Etc. + +By using `list (lazy (\_ -> comment))` we make sure the decoder only expands +to be as deep as the JSON we are given. You can read more about recursive data +structures [here][]. + +[here]: https://github.com/elm-lang/elm-compiler/blob/master/hints/recursive-alias.md +-} +lazy : (() -> Decoder a) -> Decoder a +lazy thunk = + andThen thunk (succeed ()) + + +{-| Do not do anything with a JSON value, just bring it into Elm as a `Value`. +This can be useful if you have particularly crazy data that you would like to +deal with later. Or if you are going to send it out a port and do not care +about its structure. +-} +value : Decoder Value +value = + Native.Json.decodePrimitive "value" + + +{-| Decode a `null` value into some Elm value. + + decodeString (null False) "null" == Ok False + decodeString (null 42) "null" == Ok 42 + decodeString (null 42) "42" == Err .. + decodeString (null 42) "false" == Err .. + +So if you ever see a `null`, this will return whatever value you specified. +-} +null : a -> Decoder a +null = + Native.Json.decodeNull diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Json/Encode.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Json/Encode.elm new file mode 100644 index 0000000..29e6fc9 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Json/Encode.elm @@ -0,0 +1,102 @@ +module Json.Encode exposing + ( Value + , encode + , string, int, float, bool, null + , list, array + , object + ) + +{-| Library for turning Elm values into Json values. + +# Encoding +@docs encode, Value + +# Primitives +@docs string, int, float, bool, null + +# Arrays +@docs list, array + +# Objects +@docs object +-} + +import Array exposing (Array) +import Native.Json + + +{-| Represents a JavaScript value. +-} +type Value = Value + + +{-| Convert a `Value` into a prettified string. The first argument specifies +the amount of indentation in the resulting string. + + person = + object + [ ("name", string "Tom") + , ("age", int 42) + ] + + compact = encode 0 person + -- {"name":"Tom","age":42} + + readable = encode 4 person + -- { + -- "name": "Tom", + -- "age": 42 + -- } +-} +encode : Int -> Value -> String +encode = + Native.Json.encode + + +{-|-} +string : String -> Value +string = + Native.Json.identity + + +{-|-} +int : Int -> Value +int = + Native.Json.identity + + +{-| Encode a Float. `Infinity` and `NaN` are encoded as `null`. +-} +float : Float -> Value +float = + Native.Json.identity + + +{-|-} +bool : Bool -> Value +bool = + Native.Json.identity + + +{-|-} +null : Value +null = + Native.Json.encodeNull + + +{-|-} +object : List (String, Value) -> Value +object = + Native.Json.encodeObject + + +{-|-} +array : Array Value -> Value +array = + Native.Json.encodeArray + + +{-|-} +list : List Value -> Value +list = + Native.Json.encodeList diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/List.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/List.elm new file mode 100644 index 0000000..0b7ddf9 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/List.elm @@ -0,0 +1,613 @@ +module List exposing + ( isEmpty, length, reverse, member + , head, tail, filter, take, drop + , singleton, repeat, range, (::), append, concat, intersperse + , partition, unzip + , map, map2, map3, map4, map5 + , filterMap, concatMap, indexedMap + , foldr, foldl + , sum, product, maximum, minimum, all, any, scanl + , sort, sortBy, sortWith + ) + +{-| A library for manipulating lists of values. Every value in a +list must have the same type. + +# Basics +@docs isEmpty, length, reverse, member + +# Sub-lists +@docs head, tail, filter, take, drop + +# Putting Lists Together +@docs singleton, repeat, range, (::), append, concat, intersperse + +# Taking Lists Apart +@docs partition, unzip + +# Mapping +@docs map, map2, map3, map4, map5 + +If you can think of a legitimate use of `mapN` where `N` is 6 or more, please +let us know on [the list](https://groups.google.com/forum/#!forum/elm-discuss). +The current sentiment is that it is already quite error prone once you get to +4 and possibly should be approached another way. + +# Special Maps +@docs filterMap, concatMap, indexedMap + +# Folding +@docs foldr, foldl + +# Special Folds +@docs sum, product, maximum, minimum, all, any, scanl + +# Sorting +@docs sort, sortBy, sortWith + +-} + +import Basics exposing (..) +import Maybe +import Maybe exposing ( Maybe(Just,Nothing) ) +import Native.List + + +{-| Add an element to the front of a list. Pronounced *cons*. + + 1 :: [2,3] == [1,2,3] + 1 :: [] == [1] +-} +(::) : a -> List a -> List a +(::) = + Native.List.cons + + +infixr 5 :: + + +{-| Extract the first element of a list. + + head [1,2,3] == Just 1 + head [] == Nothing +-} +head : List a -> Maybe a +head list = + case list of + x :: xs -> + Just x + + [] -> + Nothing + + +{-| Extract the rest of the list. + + tail [1,2,3] == Just [2,3] + tail [] == Nothing +-} +tail : List a -> Maybe (List a) +tail list = + case list of + x :: xs -> + Just xs + + [] -> + Nothing + + +{-| Determine if a list is empty. + + isEmpty [] == True +-} +isEmpty : List a -> Bool +isEmpty xs = + case xs of + [] -> + True + + _ -> + False + + +{-| Figure out whether a list contains a value. + + member 9 [1,2,3,4] == False + member 4 [1,2,3,4] == True +-} +member : a -> List a -> Bool +member x xs = + any (\a -> a == x) xs + + +{-| Apply a function to every element of a list. + + map sqrt [1,4,9] == [1,2,3] + + map not [True,False,True] == [False,True,False] +-} +map : (a -> b) -> List a -> List b +map f xs = + foldr (\x acc -> f x :: acc) [] xs + + +{-| Same as `map` but the function is also applied to the index of each +element (starting at zero). + + indexedMap (,) ["Tom","Sue","Bob"] == [ (0,"Tom"), (1,"Sue"), (2,"Bob") ] +-} +indexedMap : (Int -> a -> b) -> List a -> List b +indexedMap f xs = + map2 f (range 0 (length xs - 1)) xs + + +{-| Reduce a list from the left. + + foldl (::) [] [1,2,3] == [3,2,1] +-} +foldl : (a -> b -> b) -> b -> List a -> b +foldl func acc list = + case list of + [] -> + acc + + x :: xs -> + foldl func (func x acc) xs + + +{-| Reduce a list from the right. + + foldr (+) 0 [1,2,3] == 6 +-} +foldr : (a -> b -> b) -> b -> List a -> b +foldr = + Native.List.foldr + + +{-| Reduce a list from the left, building up all of the intermediate results into a list. + + scanl (+) 0 [1,2,3,4] == [0,1,3,6,10] +-} +scanl : (a -> b -> b) -> b -> List a -> List b +scanl f b xs = + let + scan1 x accAcc = + case accAcc of + acc :: _ -> + f x acc :: accAcc + + [] -> + [] -- impossible + in + reverse (foldl scan1 [b] xs) + + +{-| Keep only elements that satisfy the predicate. + + filter isEven [1,2,3,4,5,6] == [2,4,6] +-} +filter : (a -> Bool) -> List a -> List a +filter pred xs = + let + conditionalCons front back = + if pred front then + front :: back + + else + back + in + foldr conditionalCons [] xs + + +{-| Apply a function that may succeed to all values in the list, but only keep +the successes. + + onlyTeens = + filterMap isTeen [3, 15, 12, 18, 24] == [15, 18] + + isTeen : Int -> Maybe Int + isTeen n = + if 13 <= n && n <= 19 then + Just n + + else + Nothing +-} +filterMap : (a -> Maybe b) -> List a -> List b +filterMap f xs = + foldr (maybeCons f) [] xs + + +maybeCons : (a -> Maybe b) -> a -> List b -> List b +maybeCons f mx xs = + case f mx of + Just x -> + x :: xs + + Nothing -> + xs + + +{-| Determine the length of a list. + + length [1,2,3] == 3 +-} +length : List a -> Int +length xs = + foldl (\_ i -> i + 1) 0 xs + + +{-| Reverse a list. + + reverse [1,2,3,4] == [4,3,2,1] +-} +reverse : List a -> List a +reverse list = + foldl (::) [] list + + +{-| Determine if all elements satisfy the predicate. + + all isEven [2,4] == True + all isEven [2,3] == False + all isEven [] == True +-} +all : (a -> Bool) -> List a -> Bool +all isOkay list = + not (any (not << isOkay) list) + + +{-| Determine if any elements satisfy the predicate. + + any isEven [2,3] == True + any isEven [1,3] == False + any isEven [] == False +-} +any : (a -> Bool) -> List a -> Bool +any isOkay list = + case list of + [] -> + False + + x :: xs -> + -- note: (isOkay x || any isOkay xs) would not get TCO + if isOkay x then + True + + else + any isOkay xs + + +{-| Put two lists together. + + append [1,1,2] [3,5,8] == [1,1,2,3,5,8] + append ['a','b'] ['c'] == ['a','b','c'] + +You can also use [the `(++)` operator](Basics#++) to append lists. +-} +append : List a -> List a -> List a +append xs ys = + case ys of + [] -> + xs + + _ -> + foldr (::) ys xs + + +{-| Concatenate a bunch of lists into a single list: + + concat [[1,2],[3],[4,5]] == [1,2,3,4,5] +-} +concat : List (List a) -> List a +concat lists = + foldr append [] lists + + +{-| Map a given function onto a list and flatten the resulting lists. + + concatMap f xs == concat (map f xs) +-} +concatMap : (a -> List b) -> List a -> List b +concatMap f list = + concat (map f list) + + +{-| Get the sum of the list elements. + + sum [1,2,3,4] == 10 +-} +sum : List number -> number +sum numbers = + foldl (+) 0 numbers + + +{-| Get the product of the list elements. + + product [1,2,3,4] == 24 +-} +product : List number -> number +product numbers = + foldl (*) 1 numbers + + +{-| Find the maximum element in a non-empty list. + + maximum [1,4,2] == Just 4 + maximum [] == Nothing +-} +maximum : List comparable -> Maybe comparable +maximum list = + case list of + x :: xs -> + Just (foldl max x xs) + + _ -> + Nothing + + +{-| Find the minimum element in a non-empty list. + + minimum [3,2,1] == Just 1 + minimum [] == Nothing +-} +minimum : List comparable -> Maybe comparable +minimum list = + case list of + x :: xs -> + Just (foldl min x xs) + + _ -> + Nothing + + +{-| Partition a list based on a predicate. The first list contains all values +that satisfy the predicate, and the second list contains all the value that do +not. + + partition (\x -> x < 3) [0,1,2,3,4,5] == ([0,1,2], [3,4,5]) + partition isEven [0,1,2,3,4,5] == ([0,2,4], [1,3,5]) +-} +partition : (a -> Bool) -> List a -> (List a, List a) +partition pred list = + let + step x (trues, falses) = + if pred x then + (x :: trues, falses) + + else + (trues, x :: falses) + in + foldr step ([],[]) list + + +{-| Combine two lists, combining them with the given function. +If one list is longer, the extra elements are dropped. + + map2 (+) [1,2,3] [1,2,3,4] == [2,4,6] + + map2 (,) [1,2,3] ['a','b'] == [ (1,'a'), (2,'b') ] + + pairs : List a -> List b -> List (a,b) + pairs lefts rights = + map2 (,) lefts rights +-} +map2 : (a -> b -> result) -> List a -> List b -> List result +map2 = + Native.List.map2 + + +{-|-} +map3 : (a -> b -> c -> result) -> List a -> List b -> List c -> List result +map3 = + Native.List.map3 + + +{-|-} +map4 : (a -> b -> c -> d -> result) -> List a -> List b -> List c -> List d -> List result +map4 = + Native.List.map4 + + +{-|-} +map5 : (a -> b -> c -> d -> e -> result) -> List a -> List b -> List c -> List d -> List e -> List result +map5 = + Native.List.map5 + + +{-| Decompose a list of tuples into a tuple of lists. + + unzip [(0, True), (17, False), (1337, True)] == ([0,17,1337], [True,False,True]) +-} +unzip : List (a,b) -> (List a, List b) +unzip pairs = + let + step (x,y) (xs,ys) = + (x :: xs, y :: ys) + in + foldr step ([], []) pairs + + +{-| Places the given value between all members of the given list. + + intersperse "on" ["turtles","turtles","turtles"] == ["turtles","on","turtles","on","turtles"] +-} +intersperse : a -> List a -> List a +intersperse sep xs = + case xs of + [] -> + [] + + hd :: tl -> + let + step x rest = + sep :: x :: rest + + spersed = + foldr step [] tl + in + hd :: spersed + + +{-| Take the first *n* members of a list. + + take 2 [1,2,3,4] == [1,2] +-} +take : Int -> List a -> List a +take n list = + takeFast 0 n list + + +takeFast : Int -> Int -> List a -> List a +takeFast ctr n list = + if n <= 0 then + [] + else + case ( n, list ) of + ( _, [] ) -> + list + + ( 1, x :: _ ) -> + [ x ] + + ( 2, x :: y :: _ ) -> + [ x, y ] + + ( 3, x :: y :: z :: _ ) -> + [ x, y, z ] + + ( _, x :: y :: z :: w :: tl ) -> + if ctr > 1000 then + x :: y :: z :: w :: takeTailRec (n - 4) tl + else + x :: y :: z :: w :: takeFast (ctr + 1) (n - 4) tl + + _ -> + list + +takeTailRec : Int -> List a -> List a +takeTailRec n list = + reverse (takeReverse n list []) + + +takeReverse : Int -> List a -> List a -> List a +takeReverse n list taken = + if n <= 0 then + taken + else + case list of + [] -> + taken + + x :: xs -> + takeReverse (n - 1) xs (x :: taken) + + +{-| Drop the first *n* members of a list. + + drop 2 [1,2,3,4] == [3,4] +-} +drop : Int -> List a -> List a +drop n list = + if n <= 0 then + list + + else + case list of + [] -> + list + + x :: xs -> + drop (n-1) xs + + +{-| Create a list with only one element: + + singleton 1234 == [1234] + singleton "hi" == ["hi"] +-} +singleton : a -> List a +singleton value = + [value] + + +{-| Create a list with *n* copies of a value: + + repeat 3 (0,0) == [(0,0),(0,0),(0,0)] +-} +repeat : Int -> a -> List a +repeat n value = + repeatHelp [] n value + + +repeatHelp : List a -> Int -> a -> List a +repeatHelp result n value = + if n <= 0 then + result + + else + repeatHelp (value :: result) (n-1) value + + +{-| Create a list of numbers, every element increasing by one. +You give the lowest and highest number that should be in the list. + + range 3 6 == [3, 4, 5, 6] + range 3 3 == [3] + range 6 3 == [] +-} +range : Int -> Int -> List Int +range lo hi = + rangeHelp lo hi [] + + +rangeHelp : Int -> Int -> List Int -> List Int +rangeHelp lo hi list = + if lo <= hi then + rangeHelp lo (hi - 1) (hi :: list) + + else + list + + +{-| Sort values from lowest to highest + + sort [3,1,5] == [1,3,5] +-} +sort : List comparable -> List comparable +sort xs = + sortBy identity xs + + +{-| Sort values by a derived property. + + alice = { name="Alice", height=1.62 } + bob = { name="Bob" , height=1.85 } + chuck = { name="Chuck", height=1.76 } + + sortBy .name [chuck,alice,bob] == [alice,bob,chuck] + sortBy .height [chuck,alice,bob] == [alice,chuck,bob] + + sortBy String.length ["mouse","cat"] == ["cat","mouse"] +-} +sortBy : (a -> comparable) -> List a -> List a +sortBy = + Native.List.sortBy + + +{-| Sort values with a custom comparison function. + + sortWith flippedComparison [1,2,3,4,5] == [5,4,3,2,1] + + flippedComparison a b = + case compare a b of + LT -> GT + EQ -> EQ + GT -> LT + +This is also the most general sort function, allowing you +to define any other: `sort == sortWith compare` +-} +sortWith : (a -> a -> Order) -> List a -> List a +sortWith = + Native.List.sortWith diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Maybe.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Maybe.elm new file mode 100644 index 0000000..337a246 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Maybe.elm @@ -0,0 +1,157 @@ +module Maybe exposing + ( Maybe(Just,Nothing) + , andThen + , map, map2, map3, map4, map5 + , withDefault + ) + +{-| This library fills a bunch of important niches in Elm. A `Maybe` can help +you with optional arguments, error handling, and records with optional fields. + +# Definition +@docs Maybe + +# Common Helpers +@docs withDefault, map, map2, map3, map4, map5 + +# Chaining Maybes +@docs andThen +-} + +{-| Represent values that may or may not exist. It can be useful if you have a +record field that is only filled in sometimes. Or if a function takes a value +sometimes, but does not absolutely need it. + + -- A person, but maybe we do not know their age. + type alias Person = + { name : String + , age : Maybe Int + } + + tom = { name = "Tom", age = Just 42 } + sue = { name = "Sue", age = Nothing } +-} +type Maybe a + = Just a + | Nothing + + +{-| Provide a default value, turning an optional value into a normal +value. This comes in handy when paired with functions like +[`Dict.get`](Dict#get) which gives back a `Maybe`. + + withDefault 100 (Just 42) -- 42 + withDefault 100 Nothing -- 100 + + withDefault "unknown" (Dict.get "Tom" Dict.empty) -- "unknown" + +-} +withDefault : a -> Maybe a -> a +withDefault default maybe = + case maybe of + Just value -> value + Nothing -> default + + +{-| Transform a `Maybe` value with a given function: + + map sqrt (Just 9) == Just 3 + map sqrt Nothing == Nothing +-} +map : (a -> b) -> Maybe a -> Maybe b +map f maybe = + case maybe of + Just value -> Just (f value) + Nothing -> Nothing + + +{-| Apply a function if all the arguments are `Just` a value. + + map2 (+) (Just 3) (Just 4) == Just 7 + map2 (+) (Just 3) Nothing == Nothing + map2 (+) Nothing (Just 4) == Nothing +-} +map2 : (a -> b -> value) -> Maybe a -> Maybe b -> Maybe value +map2 func ma mb = + case (ma,mb) of + (Just a, Just b) -> + Just (func a b) + + _ -> + Nothing + + +{-|-} +map3 : (a -> b -> c -> value) -> Maybe a -> Maybe b -> Maybe c -> Maybe value +map3 func ma mb mc = + case (ma,mb,mc) of + (Just a, Just b, Just c) -> + Just (func a b c) + + _ -> + Nothing + + +{-|-} +map4 : (a -> b -> c -> d -> value) -> Maybe a -> Maybe b -> Maybe c -> Maybe d -> Maybe value +map4 func ma mb mc md = + case (ma,mb,mc,md) of + (Just a, Just b, Just c, Just d) -> + Just (func a b c d) + + _ -> + Nothing + + +{-|-} +map5 : (a -> b -> c -> d -> e -> value) -> Maybe a -> Maybe b -> Maybe c -> Maybe d -> Maybe e -> Maybe value +map5 func ma mb mc md me = + case (ma,mb,mc,md,me) of + (Just a, Just b, Just c, Just d, Just e) -> + Just (func a b c d e) + + _ -> + Nothing + + +{-| Chain together many computations that may fail. It is helpful to see its +definition: + + andThen : (a -> Maybe b) -> Maybe a -> Maybe b + andThen callback maybe = + case maybe of + Just value -> + callback value + + Nothing -> + Nothing + +This means we only continue with the callback if things are going well. For +example, say you need to use (`head : List Int -> Maybe Int`) to get the +first month from a `List` and then make sure it is between 1 and 12: + + toValidMonth : Int -> Maybe Int + toValidMonth month = + if month >= 1 && month <= 12 then + Just month + else + Nothing + + getFirstMonth : List Int -> Maybe Int + getFirstMonth months = + head months + |> andThen toValidMonth + +If `head` fails and results in `Nothing` (because the `List` was `empty`), +this entire chain of operations will short-circuit and result in `Nothing`. +If `toValidMonth` results in `Nothing`, again the chain of computations +will result in `Nothing`. +-} +andThen : (a -> Maybe b) -> Maybe a -> Maybe b +andThen callback maybeValue = + case maybeValue of + Just value -> + callback value + + Nothing -> + Nothing diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Array.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Array.js new file mode 100644 index 0000000..7ddd42d --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Array.js @@ -0,0 +1,967 @@ +//import Native.List // + +var _elm_lang$core$Native_Array = function() { + +// A RRB-Tree has two distinct data types. +// Leaf -> "height" is always 0 +// "table" is an array of elements +// Node -> "height" is always greater than 0 +// "table" is an array of child nodes +// "lengths" is an array of accumulated lengths of the child nodes + +// M is the maximal table size. 32 seems fast. E is the allowed increase +// of search steps when concatting to find an index. Lower values will +// decrease balancing, but will increase search steps. +var M = 32; +var E = 2; + +// An empty array. +var empty = { + ctor: '_Array', + height: 0, + table: [] +}; + + +function get(i, array) +{ + if (i < 0 || i >= length(array)) + { + throw new Error( + 'Index ' + i + ' is out of range. Check the length of ' + + 'your array first or use getMaybe or getWithDefault.'); + } + return unsafeGet(i, array); +} + + +function unsafeGet(i, array) +{ + for (var x = array.height; x > 0; x--) + { + var slot = i >> (x * 5); + while (array.lengths[slot] <= i) + { + slot++; + } + if (slot > 0) + { + i -= array.lengths[slot - 1]; + } + array = array.table[slot]; + } + return array.table[i]; +} + + +// Sets the value at the index i. Only the nodes leading to i will get +// copied and updated. +function set(i, item, array) +{ + if (i < 0 || length(array) <= i) + { + return array; + } + return unsafeSet(i, item, array); +} + + +function unsafeSet(i, item, array) +{ + array = nodeCopy(array); + + if (array.height === 0) + { + array.table[i] = item; + } + else + { + var slot = getSlot(i, array); + if (slot > 0) + { + i -= array.lengths[slot - 1]; + } + array.table[slot] = unsafeSet(i, item, array.table[slot]); + } + return array; +} + + +function initialize(len, f) +{ + if (len <= 0) + { + return empty; + } + var h = Math.floor( Math.log(len) / Math.log(M) ); + return initialize_(f, h, 0, len); +} + +function initialize_(f, h, from, to) +{ + if (h === 0) + { + var table = new Array((to - from) % (M + 1)); + for (var i = 0; i < table.length; i++) + { + table[i] = f(from + i); + } + return { + ctor: '_Array', + height: 0, + table: table + }; + } + + var step = Math.pow(M, h); + var table = new Array(Math.ceil((to - from) / step)); + var lengths = new Array(table.length); + for (var i = 0; i < table.length; i++) + { + table[i] = initialize_(f, h - 1, from + (i * step), Math.min(from + ((i + 1) * step), to)); + lengths[i] = length(table[i]) + (i > 0 ? lengths[i-1] : 0); + } + return { + ctor: '_Array', + height: h, + table: table, + lengths: lengths + }; +} + +function fromList(list) +{ + if (list.ctor === '[]') + { + return empty; + } + + // Allocate M sized blocks (table) and write list elements to it. + var table = new Array(M); + var nodes = []; + var i = 0; + + while (list.ctor !== '[]') + { + table[i] = list._0; + list = list._1; + i++; + + // table is full, so we can push a leaf containing it into the + // next node. + if (i === M) + { + var leaf = { + ctor: '_Array', + height: 0, + table: table + }; + fromListPush(leaf, nodes); + table = new Array(M); + i = 0; + } + } + + // Maybe there is something left on the table. + if (i > 0) + { + var leaf = { + ctor: '_Array', + height: 0, + table: table.splice(0, i) + }; + fromListPush(leaf, nodes); + } + + // Go through all of the nodes and eventually push them into higher nodes. + for (var h = 0; h < nodes.length - 1; h++) + { + if (nodes[h].table.length > 0) + { + fromListPush(nodes[h], nodes); + } + } + + var head = nodes[nodes.length - 1]; + if (head.height > 0 && head.table.length === 1) + { + return head.table[0]; + } + else + { + return head; + } +} + +// Push a node into a higher node as a child. +function fromListPush(toPush, nodes) +{ + var h = toPush.height; + + // Maybe the node on this height does not exist. + if (nodes.length === h) + { + var node = { + ctor: '_Array', + height: h + 1, + table: [], + lengths: [] + }; + nodes.push(node); + } + + nodes[h].table.push(toPush); + var len = length(toPush); + if (nodes[h].lengths.length > 0) + { + len += nodes[h].lengths[nodes[h].lengths.length - 1]; + } + nodes[h].lengths.push(len); + + if (nodes[h].table.length === M) + { + fromListPush(nodes[h], nodes); + nodes[h] = { + ctor: '_Array', + height: h + 1, + table: [], + lengths: [] + }; + } +} + +// Pushes an item via push_ to the bottom right of a tree. +function push(item, a) +{ + var pushed = push_(item, a); + if (pushed !== null) + { + return pushed; + } + + var newTree = create(item, a.height); + return siblise(a, newTree); +} + +// Recursively tries to push an item to the bottom-right most +// tree possible. If there is no space left for the item, +// null will be returned. +function push_(item, a) +{ + // Handle resursion stop at leaf level. + if (a.height === 0) + { + if (a.table.length < M) + { + var newA = { + ctor: '_Array', + height: 0, + table: a.table.slice() + }; + newA.table.push(item); + return newA; + } + else + { + return null; + } + } + + // Recursively push + var pushed = push_(item, botRight(a)); + + // There was space in the bottom right tree, so the slot will + // be updated. + if (pushed !== null) + { + var newA = nodeCopy(a); + newA.table[newA.table.length - 1] = pushed; + newA.lengths[newA.lengths.length - 1]++; + return newA; + } + + // When there was no space left, check if there is space left + // for a new slot with a tree which contains only the item + // at the bottom. + if (a.table.length < M) + { + var newSlot = create(item, a.height - 1); + var newA = nodeCopy(a); + newA.table.push(newSlot); + newA.lengths.push(newA.lengths[newA.lengths.length - 1] + length(newSlot)); + return newA; + } + else + { + return null; + } +} + +// Converts an array into a list of elements. +function toList(a) +{ + return toList_(_elm_lang$core$Native_List.Nil, a); +} + +function toList_(list, a) +{ + for (var i = a.table.length - 1; i >= 0; i--) + { + list = + a.height === 0 + ? _elm_lang$core$Native_List.Cons(a.table[i], list) + : toList_(list, a.table[i]); + } + return list; +} + +// Maps a function over the elements of an array. +function map(f, a) +{ + var newA = { + ctor: '_Array', + height: a.height, + table: new Array(a.table.length) + }; + if (a.height > 0) + { + newA.lengths = a.lengths; + } + for (var i = 0; i < a.table.length; i++) + { + newA.table[i] = + a.height === 0 + ? f(a.table[i]) + : map(f, a.table[i]); + } + return newA; +} + +// Maps a function over the elements with their index as first argument. +function indexedMap(f, a) +{ + return indexedMap_(f, a, 0); +} + +function indexedMap_(f, a, from) +{ + var newA = { + ctor: '_Array', + height: a.height, + table: new Array(a.table.length) + }; + if (a.height > 0) + { + newA.lengths = a.lengths; + } + for (var i = 0; i < a.table.length; i++) + { + newA.table[i] = + a.height === 0 + ? A2(f, from + i, a.table[i]) + : indexedMap_(f, a.table[i], i == 0 ? from : from + a.lengths[i - 1]); + } + return newA; +} + +function foldl(f, b, a) +{ + if (a.height === 0) + { + for (var i = 0; i < a.table.length; i++) + { + b = A2(f, a.table[i], b); + } + } + else + { + for (var i = 0; i < a.table.length; i++) + { + b = foldl(f, b, a.table[i]); + } + } + return b; +} + +function foldr(f, b, a) +{ + if (a.height === 0) + { + for (var i = a.table.length; i--; ) + { + b = A2(f, a.table[i], b); + } + } + else + { + for (var i = a.table.length; i--; ) + { + b = foldr(f, b, a.table[i]); + } + } + return b; +} + +// TODO: currently, it slices the right, then the left. This can be +// optimized. +function slice(from, to, a) +{ + if (from < 0) + { + from += length(a); + } + if (to < 0) + { + to += length(a); + } + return sliceLeft(from, sliceRight(to, a)); +} + +function sliceRight(to, a) +{ + if (to === length(a)) + { + return a; + } + + // Handle leaf level. + if (a.height === 0) + { + var newA = { ctor:'_Array', height:0 }; + newA.table = a.table.slice(0, to); + return newA; + } + + // Slice the right recursively. + var right = getSlot(to, a); + var sliced = sliceRight(to - (right > 0 ? a.lengths[right - 1] : 0), a.table[right]); + + // Maybe the a node is not even needed, as sliced contains the whole slice. + if (right === 0) + { + return sliced; + } + + // Create new node. + var newA = { + ctor: '_Array', + height: a.height, + table: a.table.slice(0, right), + lengths: a.lengths.slice(0, right) + }; + if (sliced.table.length > 0) + { + newA.table[right] = sliced; + newA.lengths[right] = length(sliced) + (right > 0 ? newA.lengths[right - 1] : 0); + } + return newA; +} + +function sliceLeft(from, a) +{ + if (from === 0) + { + return a; + } + + // Handle leaf level. + if (a.height === 0) + { + var newA = { ctor:'_Array', height:0 }; + newA.table = a.table.slice(from, a.table.length + 1); + return newA; + } + + // Slice the left recursively. + var left = getSlot(from, a); + var sliced = sliceLeft(from - (left > 0 ? a.lengths[left - 1] : 0), a.table[left]); + + // Maybe the a node is not even needed, as sliced contains the whole slice. + if (left === a.table.length - 1) + { + return sliced; + } + + // Create new node. + var newA = { + ctor: '_Array', + height: a.height, + table: a.table.slice(left, a.table.length + 1), + lengths: new Array(a.table.length - left) + }; + newA.table[0] = sliced; + var len = 0; + for (var i = 0; i < newA.table.length; i++) + { + len += length(newA.table[i]); + newA.lengths[i] = len; + } + + return newA; +} + +// Appends two trees. +function append(a,b) +{ + if (a.table.length === 0) + { + return b; + } + if (b.table.length === 0) + { + return a; + } + + var c = append_(a, b); + + // Check if both nodes can be crunshed together. + if (c[0].table.length + c[1].table.length <= M) + { + if (c[0].table.length === 0) + { + return c[1]; + } + if (c[1].table.length === 0) + { + return c[0]; + } + + // Adjust .table and .lengths + c[0].table = c[0].table.concat(c[1].table); + if (c[0].height > 0) + { + var len = length(c[0]); + for (var i = 0; i < c[1].lengths.length; i++) + { + c[1].lengths[i] += len; + } + c[0].lengths = c[0].lengths.concat(c[1].lengths); + } + + return c[0]; + } + + if (c[0].height > 0) + { + var toRemove = calcToRemove(a, b); + if (toRemove > E) + { + c = shuffle(c[0], c[1], toRemove); + } + } + + return siblise(c[0], c[1]); +} + +// Returns an array of two nodes; right and left. One node _may_ be empty. +function append_(a, b) +{ + if (a.height === 0 && b.height === 0) + { + return [a, b]; + } + + if (a.height !== 1 || b.height !== 1) + { + if (a.height === b.height) + { + a = nodeCopy(a); + b = nodeCopy(b); + var appended = append_(botRight(a), botLeft(b)); + + insertRight(a, appended[1]); + insertLeft(b, appended[0]); + } + else if (a.height > b.height) + { + a = nodeCopy(a); + var appended = append_(botRight(a), b); + + insertRight(a, appended[0]); + b = parentise(appended[1], appended[1].height + 1); + } + else + { + b = nodeCopy(b); + var appended = append_(a, botLeft(b)); + + var left = appended[0].table.length === 0 ? 0 : 1; + var right = left === 0 ? 1 : 0; + insertLeft(b, appended[left]); + a = parentise(appended[right], appended[right].height + 1); + } + } + + // Check if balancing is needed and return based on that. + if (a.table.length === 0 || b.table.length === 0) + { + return [a, b]; + } + + var toRemove = calcToRemove(a, b); + if (toRemove <= E) + { + return [a, b]; + } + return shuffle(a, b, toRemove); +} + +// Helperfunctions for append_. Replaces a child node at the side of the parent. +function insertRight(parent, node) +{ + var index = parent.table.length - 1; + parent.table[index] = node; + parent.lengths[index] = length(node); + parent.lengths[index] += index > 0 ? parent.lengths[index - 1] : 0; +} + +function insertLeft(parent, node) +{ + if (node.table.length > 0) + { + parent.table[0] = node; + parent.lengths[0] = length(node); + + var len = length(parent.table[0]); + for (var i = 1; i < parent.lengths.length; i++) + { + len += length(parent.table[i]); + parent.lengths[i] = len; + } + } + else + { + parent.table.shift(); + for (var i = 1; i < parent.lengths.length; i++) + { + parent.lengths[i] = parent.lengths[i] - parent.lengths[0]; + } + parent.lengths.shift(); + } +} + +// Returns the extra search steps for E. Refer to the paper. +function calcToRemove(a, b) +{ + var subLengths = 0; + for (var i = 0; i < a.table.length; i++) + { + subLengths += a.table[i].table.length; + } + for (var i = 0; i < b.table.length; i++) + { + subLengths += b.table[i].table.length; + } + + var toRemove = a.table.length + b.table.length; + return toRemove - (Math.floor((subLengths - 1) / M) + 1); +} + +// get2, set2 and saveSlot are helpers for accessing elements over two arrays. +function get2(a, b, index) +{ + return index < a.length + ? a[index] + : b[index - a.length]; +} + +function set2(a, b, index, value) +{ + if (index < a.length) + { + a[index] = value; + } + else + { + b[index - a.length] = value; + } +} + +function saveSlot(a, b, index, slot) +{ + set2(a.table, b.table, index, slot); + + var l = (index === 0 || index === a.lengths.length) + ? 0 + : get2(a.lengths, a.lengths, index - 1); + + set2(a.lengths, b.lengths, index, l + length(slot)); +} + +// Creates a node or leaf with a given length at their arrays for perfomance. +// Is only used by shuffle. +function createNode(h, length) +{ + if (length < 0) + { + length = 0; + } + var a = { + ctor: '_Array', + height: h, + table: new Array(length) + }; + if (h > 0) + { + a.lengths = new Array(length); + } + return a; +} + +// Returns an array of two balanced nodes. +function shuffle(a, b, toRemove) +{ + var newA = createNode(a.height, Math.min(M, a.table.length + b.table.length - toRemove)); + var newB = createNode(a.height, newA.table.length - (a.table.length + b.table.length - toRemove)); + + // Skip the slots with size M. More precise: copy the slot references + // to the new node + var read = 0; + while (get2(a.table, b.table, read).table.length % M === 0) + { + set2(newA.table, newB.table, read, get2(a.table, b.table, read)); + set2(newA.lengths, newB.lengths, read, get2(a.lengths, b.lengths, read)); + read++; + } + + // Pulling items from left to right, caching in a slot before writing + // it into the new nodes. + var write = read; + var slot = new createNode(a.height - 1, 0); + var from = 0; + + // If the current slot is still containing data, then there will be at + // least one more write, so we do not break this loop yet. + while (read - write - (slot.table.length > 0 ? 1 : 0) < toRemove) + { + // Find out the max possible items for copying. + var source = get2(a.table, b.table, read); + var to = Math.min(M - slot.table.length, source.table.length); + + // Copy and adjust size table. + slot.table = slot.table.concat(source.table.slice(from, to)); + if (slot.height > 0) + { + var len = slot.lengths.length; + for (var i = len; i < len + to - from; i++) + { + slot.lengths[i] = length(slot.table[i]); + slot.lengths[i] += (i > 0 ? slot.lengths[i - 1] : 0); + } + } + + from += to; + + // Only proceed to next slots[i] if the current one was + // fully copied. + if (source.table.length <= to) + { + read++; from = 0; + } + + // Only create a new slot if the current one is filled up. + if (slot.table.length === M) + { + saveSlot(newA, newB, write, slot); + slot = createNode(a.height - 1, 0); + write++; + } + } + + // Cleanup after the loop. Copy the last slot into the new nodes. + if (slot.table.length > 0) + { + saveSlot(newA, newB, write, slot); + write++; + } + + // Shift the untouched slots to the left + while (read < a.table.length + b.table.length ) + { + saveSlot(newA, newB, write, get2(a.table, b.table, read)); + read++; + write++; + } + + return [newA, newB]; +} + +// Navigation functions +function botRight(a) +{ + return a.table[a.table.length - 1]; +} +function botLeft(a) +{ + return a.table[0]; +} + +// Copies a node for updating. Note that you should not use this if +// only updating only one of "table" or "lengths" for performance reasons. +function nodeCopy(a) +{ + var newA = { + ctor: '_Array', + height: a.height, + table: a.table.slice() + }; + if (a.height > 0) + { + newA.lengths = a.lengths.slice(); + } + return newA; +} + +// Returns how many items are in the tree. +function length(array) +{ + if (array.height === 0) + { + return array.table.length; + } + else + { + return array.lengths[array.lengths.length - 1]; + } +} + +// Calculates in which slot of "table" the item probably is, then +// find the exact slot via forward searching in "lengths". Returns the index. +function getSlot(i, a) +{ + var slot = i >> (5 * a.height); + while (a.lengths[slot] <= i) + { + slot++; + } + return slot; +} + +// Recursively creates a tree with a given height containing +// only the given item. +function create(item, h) +{ + if (h === 0) + { + return { + ctor: '_Array', + height: 0, + table: [item] + }; + } + return { + ctor: '_Array', + height: h, + table: [create(item, h - 1)], + lengths: [1] + }; +} + +// Recursively creates a tree that contains the given tree. +function parentise(tree, h) +{ + if (h === tree.height) + { + return tree; + } + + return { + ctor: '_Array', + height: h, + table: [parentise(tree, h - 1)], + lengths: [length(tree)] + }; +} + +// Emphasizes blood brotherhood beneath two trees. +function siblise(a, b) +{ + return { + ctor: '_Array', + height: a.height + 1, + table: [a, b], + lengths: [length(a), length(a) + length(b)] + }; +} + +function toJSArray(a) +{ + var jsArray = new Array(length(a)); + toJSArray_(jsArray, 0, a); + return jsArray; +} + +function toJSArray_(jsArray, i, a) +{ + for (var t = 0; t < a.table.length; t++) + { + if (a.height === 0) + { + jsArray[i + t] = a.table[t]; + } + else + { + var inc = t === 0 ? 0 : a.lengths[t - 1]; + toJSArray_(jsArray, i + inc, a.table[t]); + } + } +} + +function fromJSArray(jsArray) +{ + if (jsArray.length === 0) + { + return empty; + } + var h = Math.floor(Math.log(jsArray.length) / Math.log(M)); + return fromJSArray_(jsArray, h, 0, jsArray.length); +} + +function fromJSArray_(jsArray, h, from, to) +{ + if (h === 0) + { + return { + ctor: '_Array', + height: 0, + table: jsArray.slice(from, to) + }; + } + + var step = Math.pow(M, h); + var table = new Array(Math.ceil((to - from) / step)); + var lengths = new Array(table.length); + for (var i = 0; i < table.length; i++) + { + table[i] = fromJSArray_(jsArray, h - 1, from + (i * step), Math.min(from + ((i + 1) * step), to)); + lengths[i] = length(table[i]) + (i > 0 ? lengths[i - 1] : 0); + } + return { + ctor: '_Array', + height: h, + table: table, + lengths: lengths + }; +} + +return { + empty: empty, + fromList: fromList, + toList: toList, + initialize: F2(initialize), + append: F2(append), + push: F2(push), + slice: F3(slice), + get: F2(get), + set: F3(set), + map: F2(map), + indexedMap: F2(indexedMap), + foldl: F3(foldl), + foldr: F3(foldr), + length: length, + + toJSArray: toJSArray, + fromJSArray: fromJSArray +}; + +}(); \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Basics.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Basics.js new file mode 100644 index 0000000..1d97bf3 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Basics.js @@ -0,0 +1,141 @@ +//import Native.Utils // + +var _elm_lang$core$Native_Basics = function() { + +function div(a, b) +{ + return (a / b) | 0; +} +function rem(a, b) +{ + return a % b; +} +function mod(a, b) +{ + if (b === 0) + { + throw new Error('Cannot perform mod 0. Division by zero error.'); + } + var r = a % b; + var m = a === 0 ? 0 : (b > 0 ? (a >= 0 ? r : r + b) : -mod(-a, -b)); + + return m === b ? 0 : m; +} +function logBase(base, n) +{ + return Math.log(n) / Math.log(base); +} +function negate(n) +{ + return -n; +} +function abs(n) +{ + return n < 0 ? -n : n; +} + +function min(a, b) +{ + return _elm_lang$core$Native_Utils.cmp(a, b) < 0 ? a : b; +} +function max(a, b) +{ + return _elm_lang$core$Native_Utils.cmp(a, b) > 0 ? a : b; +} +function clamp(lo, hi, n) +{ + return _elm_lang$core$Native_Utils.cmp(n, lo) < 0 + ? lo + : _elm_lang$core$Native_Utils.cmp(n, hi) > 0 + ? hi + : n; +} + +var ord = ['LT', 'EQ', 'GT']; + +function compare(x, y) +{ + return { ctor: ord[_elm_lang$core$Native_Utils.cmp(x, y) + 1] }; +} + +function xor(a, b) +{ + return a !== b; +} +function not(b) +{ + return !b; +} +function isInfinite(n) +{ + return n === Infinity || n === -Infinity; +} + +function truncate(n) +{ + return n | 0; +} + +function degrees(d) +{ + return d * Math.PI / 180; +} +function turns(t) +{ + return 2 * Math.PI * t; +} +function fromPolar(point) +{ + var r = point._0; + var t = point._1; + return _elm_lang$core$Native_Utils.Tuple2(r * Math.cos(t), r * Math.sin(t)); +} +function toPolar(point) +{ + var x = point._0; + var y = point._1; + return _elm_lang$core$Native_Utils.Tuple2(Math.sqrt(x * x + y * y), Math.atan2(y, x)); +} + +return { + div: F2(div), + rem: F2(rem), + mod: F2(mod), + + pi: Math.PI, + e: Math.E, + cos: Math.cos, + sin: Math.sin, + tan: Math.tan, + acos: Math.acos, + asin: Math.asin, + atan: Math.atan, + atan2: F2(Math.atan2), + + degrees: degrees, + turns: turns, + fromPolar: fromPolar, + toPolar: toPolar, + + sqrt: Math.sqrt, + logBase: F2(logBase), + negate: negate, + abs: abs, + min: F2(min), + max: F2(max), + clamp: F3(clamp), + compare: F2(compare), + + xor: F2(xor), + not: not, + + truncate: truncate, + ceiling: Math.ceil, + floor: Math.floor, + round: Math.round, + toFloat: function(x) { return x; }, + isNaN: isNaN, + isInfinite: isInfinite +}; + +}(); \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Bitwise.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Bitwise.js new file mode 100644 index 0000000..a597f82 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Bitwise.js @@ -0,0 +1,13 @@ +var _elm_lang$core$Native_Bitwise = function() { + +return { + and: F2(function and(a, b) { return a & b; }), + or: F2(function or(a, b) { return a | b; }), + xor: F2(function xor(a, b) { return a ^ b; }), + complement: function complement(a) { return ~a; }, + shiftLeftBy: F2(function(offset, a) { return a << offset; }), + shiftRightBy: F2(function(offset, a) { return a >> offset; }), + shiftRightZfBy: F2(function(offset, a) { return a >>> offset; }) +}; + +}(); diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Char.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Char.js new file mode 100644 index 0000000..56c2957 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Char.js @@ -0,0 +1,14 @@ +//import Native.Utils // + +var _elm_lang$core$Native_Char = function() { + +return { + fromCode: function(c) { return _elm_lang$core$Native_Utils.chr(String.fromCharCode(c)); }, + toCode: function(c) { return c.charCodeAt(0); }, + toUpper: function(c) { return _elm_lang$core$Native_Utils.chr(c.toUpperCase()); }, + toLower: function(c) { return _elm_lang$core$Native_Utils.chr(c.toLowerCase()); }, + toLocaleUpper: function(c) { return _elm_lang$core$Native_Utils.chr(c.toLocaleUpperCase()); }, + toLocaleLower: function(c) { return _elm_lang$core$Native_Utils.chr(c.toLocaleLowerCase()); } +}; + +}(); \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Date.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Date.js new file mode 100644 index 0000000..cb64193 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Date.js @@ -0,0 +1,33 @@ +//import Result // + +var _elm_lang$core$Native_Date = function() { + +function fromString(str) +{ + var date = new Date(str); + return isNaN(date.getTime()) + ? _elm_lang$core$Result$Err('Unable to parse \'' + str + '\' as a date. Dates must be in the ISO 8601 format.') + : _elm_lang$core$Result$Ok(date); +} + +var dayTable = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; +var monthTable = + ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + + +return { + fromString: fromString, + year: function(d) { return d.getFullYear(); }, + month: function(d) { return { ctor: monthTable[d.getMonth()] }; }, + day: function(d) { return d.getDate(); }, + hour: function(d) { return d.getHours(); }, + minute: function(d) { return d.getMinutes(); }, + second: function(d) { return d.getSeconds(); }, + millisecond: function(d) { return d.getMilliseconds(); }, + toTime: function(d) { return d.getTime(); }, + fromTime: function(t) { return new Date(t); }, + dayOfWeek: function(d) { return { ctor: dayTable[d.getDay()] }; } +}; + +}(); \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Debug.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Debug.js new file mode 100644 index 0000000..15ce1dc --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Debug.js @@ -0,0 +1,30 @@ +//import Native.Utils // + +var _elm_lang$core$Native_Debug = function() { + +function log(tag, value) +{ + var msg = tag + ': ' + _elm_lang$core$Native_Utils.toString(value); + var process = process || {}; + if (process.stdout) + { + process.stdout.write(msg); + } + else + { + console.log(msg); + } + return value; +} + +function crash(message) +{ + throw new Error(message); +} + +return { + crash: crash, + log: F2(log) +}; + +}(); \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Json.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Json.js new file mode 100644 index 0000000..61df889 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Json.js @@ -0,0 +1,575 @@ +//import Maybe, Native.Array, Native.List, Native.Utils, Result // + +var _elm_lang$core$Native_Json = function() { + + +// CORE DECODERS + +function succeed(msg) +{ + return { + ctor: '', + tag: 'succeed', + msg: msg + }; +} + +function fail(msg) +{ + return { + ctor: '', + tag: 'fail', + msg: msg + }; +} + +function decodePrimitive(tag) +{ + return { + ctor: '', + tag: tag + }; +} + +function decodeContainer(tag, decoder) +{ + return { + ctor: '', + tag: tag, + decoder: decoder + }; +} + +function decodeNull(value) +{ + return { + ctor: '', + tag: 'null', + value: value + }; +} + +function decodeField(field, decoder) +{ + return { + ctor: '', + tag: 'field', + field: field, + decoder: decoder + }; +} + +function decodeIndex(index, decoder) +{ + return { + ctor: '', + tag: 'index', + index: index, + decoder: decoder + }; +} + +function decodeKeyValuePairs(decoder) +{ + return { + ctor: '', + tag: 'key-value', + decoder: decoder + }; +} + +function mapMany(f, decoders) +{ + return { + ctor: '', + tag: 'map-many', + func: f, + decoders: decoders + }; +} + +function andThen(callback, decoder) +{ + return { + ctor: '', + tag: 'andThen', + decoder: decoder, + callback: callback + }; +} + +function oneOf(decoders) +{ + return { + ctor: '', + tag: 'oneOf', + decoders: decoders + }; +} + + +// DECODING OBJECTS + +function map1(f, d1) +{ + return mapMany(f, [d1]); +} + +function map2(f, d1, d2) +{ + return mapMany(f, [d1, d2]); +} + +function map3(f, d1, d2, d3) +{ + return mapMany(f, [d1, d2, d3]); +} + +function map4(f, d1, d2, d3, d4) +{ + return mapMany(f, [d1, d2, d3, d4]); +} + +function map5(f, d1, d2, d3, d4, d5) +{ + return mapMany(f, [d1, d2, d3, d4, d5]); +} + +function map6(f, d1, d2, d3, d4, d5, d6) +{ + return mapMany(f, [d1, d2, d3, d4, d5, d6]); +} + +function map7(f, d1, d2, d3, d4, d5, d6, d7) +{ + return mapMany(f, [d1, d2, d3, d4, d5, d6, d7]); +} + +function map8(f, d1, d2, d3, d4, d5, d6, d7, d8) +{ + return mapMany(f, [d1, d2, d3, d4, d5, d6, d7, d8]); +} + + +// DECODE HELPERS + +function ok(value) +{ + return { tag: 'ok', value: value }; +} + +function badPrimitive(type, value) +{ + return { tag: 'primitive', type: type, value: value }; +} + +function badIndex(index, nestedProblems) +{ + return { tag: 'index', index: index, rest: nestedProblems }; +} + +function badField(field, nestedProblems) +{ + return { tag: 'field', field: field, rest: nestedProblems }; +} + +function badIndex(index, nestedProblems) +{ + return { tag: 'index', index: index, rest: nestedProblems }; +} + +function badOneOf(problems) +{ + return { tag: 'oneOf', problems: problems }; +} + +function bad(msg) +{ + return { tag: 'fail', msg: msg }; +} + +function badToString(problem) +{ + var context = '_'; + while (problem) + { + switch (problem.tag) + { + case 'primitive': + return 'Expecting ' + problem.type + + (context === '_' ? '' : ' at ' + context) + + ' but instead got: ' + jsToString(problem.value); + + case 'index': + context += '[' + problem.index + ']'; + problem = problem.rest; + break; + + case 'field': + context += '.' + problem.field; + problem = problem.rest; + break; + + case 'oneOf': + var problems = problem.problems; + for (var i = 0; i < problems.length; i++) + { + problems[i] = badToString(problems[i]); + } + return 'I ran into the following problems' + + (context === '_' ? '' : ' at ' + context) + + ':\n\n' + problems.join('\n'); + + case 'fail': + return 'I ran into a `fail` decoder' + + (context === '_' ? '' : ' at ' + context) + + ': ' + problem.msg; + } + } +} + +function jsToString(value) +{ + return value === undefined + ? 'undefined' + : JSON.stringify(value); +} + + +// DECODE + +function runOnString(decoder, string) +{ + var json; + try + { + json = JSON.parse(string); + } + catch (e) + { + return _elm_lang$core$Result$Err('Given an invalid JSON: ' + e.message); + } + return run(decoder, json); +} + +function run(decoder, value) +{ + var result = runHelp(decoder, value); + return (result.tag === 'ok') + ? _elm_lang$core$Result$Ok(result.value) + : _elm_lang$core$Result$Err(badToString(result)); +} + +function runHelp(decoder, value) +{ + switch (decoder.tag) + { + case 'bool': + return (typeof value === 'boolean') + ? ok(value) + : badPrimitive('a Bool', value); + + case 'int': + if (typeof value !== 'number') { + return badPrimitive('an Int', value); + } + + if (-2147483647 < value && value < 2147483647 && (value | 0) === value) { + return ok(value); + } + + if (isFinite(value) && !(value % 1)) { + return ok(value); + } + + return badPrimitive('an Int', value); + + case 'float': + return (typeof value === 'number') + ? ok(value) + : badPrimitive('a Float', value); + + case 'string': + return (typeof value === 'string') + ? ok(value) + : (value instanceof String) + ? ok(value + '') + : badPrimitive('a String', value); + + case 'null': + return (value === null) + ? ok(decoder.value) + : badPrimitive('null', value); + + case 'value': + return ok(value); + + case 'list': + if (!(value instanceof Array)) + { + return badPrimitive('a List', value); + } + + var list = _elm_lang$core$Native_List.Nil; + for (var i = value.length; i--; ) + { + var result = runHelp(decoder.decoder, value[i]); + if (result.tag !== 'ok') + { + return badIndex(i, result) + } + list = _elm_lang$core$Native_List.Cons(result.value, list); + } + return ok(list); + + case 'array': + if (!(value instanceof Array)) + { + return badPrimitive('an Array', value); + } + + var len = value.length; + var array = new Array(len); + for (var i = len; i--; ) + { + var result = runHelp(decoder.decoder, value[i]); + if (result.tag !== 'ok') + { + return badIndex(i, result); + } + array[i] = result.value; + } + return ok(_elm_lang$core$Native_Array.fromJSArray(array)); + + case 'maybe': + var result = runHelp(decoder.decoder, value); + return (result.tag === 'ok') + ? ok(_elm_lang$core$Maybe$Just(result.value)) + : ok(_elm_lang$core$Maybe$Nothing); + + case 'field': + var field = decoder.field; + if (typeof value !== 'object' || value === null || !(field in value)) + { + return badPrimitive('an object with a field named `' + field + '`', value); + } + + var result = runHelp(decoder.decoder, value[field]); + return (result.tag === 'ok') ? result : badField(field, result); + + case 'index': + var index = decoder.index; + if (!(value instanceof Array)) + { + return badPrimitive('an array', value); + } + if (index >= value.length) + { + return badPrimitive('a longer array. Need index ' + index + ' but there are only ' + value.length + ' entries', value); + } + + var result = runHelp(decoder.decoder, value[index]); + return (result.tag === 'ok') ? result : badIndex(index, result); + + case 'key-value': + if (typeof value !== 'object' || value === null || value instanceof Array) + { + return badPrimitive('an object', value); + } + + var keyValuePairs = _elm_lang$core$Native_List.Nil; + for (var key in value) + { + var result = runHelp(decoder.decoder, value[key]); + if (result.tag !== 'ok') + { + return badField(key, result); + } + var pair = _elm_lang$core$Native_Utils.Tuple2(key, result.value); + keyValuePairs = _elm_lang$core$Native_List.Cons(pair, keyValuePairs); + } + return ok(keyValuePairs); + + case 'map-many': + var answer = decoder.func; + var decoders = decoder.decoders; + for (var i = 0; i < decoders.length; i++) + { + var result = runHelp(decoders[i], value); + if (result.tag !== 'ok') + { + return result; + } + answer = answer(result.value); + } + return ok(answer); + + case 'andThen': + var result = runHelp(decoder.decoder, value); + return (result.tag !== 'ok') + ? result + : runHelp(decoder.callback(result.value), value); + + case 'oneOf': + var errors = []; + var temp = decoder.decoders; + while (temp.ctor !== '[]') + { + var result = runHelp(temp._0, value); + + if (result.tag === 'ok') + { + return result; + } + + errors.push(result); + + temp = temp._1; + } + return badOneOf(errors); + + case 'fail': + return bad(decoder.msg); + + case 'succeed': + return ok(decoder.msg); + } +} + + +// EQUALITY + +function equality(a, b) +{ + if (a === b) + { + return true; + } + + if (a.tag !== b.tag) + { + return false; + } + + switch (a.tag) + { + case 'succeed': + case 'fail': + return a.msg === b.msg; + + case 'bool': + case 'int': + case 'float': + case 'string': + case 'value': + return true; + + case 'null': + return a.value === b.value; + + case 'list': + case 'array': + case 'maybe': + case 'key-value': + return equality(a.decoder, b.decoder); + + case 'field': + return a.field === b.field && equality(a.decoder, b.decoder); + + case 'index': + return a.index === b.index && equality(a.decoder, b.decoder); + + case 'map-many': + if (a.func !== b.func) + { + return false; + } + return listEquality(a.decoders, b.decoders); + + case 'andThen': + return a.callback === b.callback && equality(a.decoder, b.decoder); + + case 'oneOf': + return listEquality(a.decoders, b.decoders); + } +} + +function listEquality(aDecoders, bDecoders) +{ + var len = aDecoders.length; + if (len !== bDecoders.length) + { + return false; + } + for (var i = 0; i < len; i++) + { + if (!equality(aDecoders[i], bDecoders[i])) + { + return false; + } + } + return true; +} + + +// ENCODE + +function encode(indentLevel, value) +{ + return JSON.stringify(value, null, indentLevel); +} + +function identity(value) +{ + return value; +} + +function encodeObject(keyValuePairs) +{ + var obj = {}; + while (keyValuePairs.ctor !== '[]') + { + var pair = keyValuePairs._0; + obj[pair._0] = pair._1; + keyValuePairs = keyValuePairs._1; + } + return obj; +} + +return { + encode: F2(encode), + runOnString: F2(runOnString), + run: F2(run), + + decodeNull: decodeNull, + decodePrimitive: decodePrimitive, + decodeContainer: F2(decodeContainer), + + decodeField: F2(decodeField), + decodeIndex: F2(decodeIndex), + + map1: F2(map1), + map2: F3(map2), + map3: F4(map3), + map4: F5(map4), + map5: F6(map5), + map6: F7(map6), + map7: F8(map7), + map8: F9(map8), + decodeKeyValuePairs: decodeKeyValuePairs, + + andThen: F2(andThen), + fail: fail, + succeed: succeed, + oneOf: oneOf, + + identity: identity, + encodeNull: null, + encodeArray: _elm_lang$core$Native_Array.toJSArray, + encodeList: _elm_lang$core$Native_List.toArray, + encodeObject: encodeObject, + + equality: equality +}; + +}(); diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/List.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/List.js new file mode 100644 index 0000000..ccefb9c --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/List.js @@ -0,0 +1,137 @@ +//import Native.Utils // + +var _elm_lang$core$Native_List = function() { + +var Nil = { ctor: '[]' }; + +function Cons(hd, tl) +{ + return { ctor: '::', _0: hd, _1: tl }; +} + +function fromArray(arr) +{ + var out = Nil; + for (var i = arr.length; i--; ) + { + out = Cons(arr[i], out); + } + return out; +} + +function toArray(xs) +{ + var out = []; + while (xs.ctor !== '[]') + { + out.push(xs._0); + xs = xs._1; + } + return out; +} + +function foldr(f, b, xs) +{ + var arr = toArray(xs); + var acc = b; + for (var i = arr.length; i--; ) + { + acc = A2(f, arr[i], acc); + } + return acc; +} + +function map2(f, xs, ys) +{ + var arr = []; + while (xs.ctor !== '[]' && ys.ctor !== '[]') + { + arr.push(A2(f, xs._0, ys._0)); + xs = xs._1; + ys = ys._1; + } + return fromArray(arr); +} + +function map3(f, xs, ys, zs) +{ + var arr = []; + while (xs.ctor !== '[]' && ys.ctor !== '[]' && zs.ctor !== '[]') + { + arr.push(A3(f, xs._0, ys._0, zs._0)); + xs = xs._1; + ys = ys._1; + zs = zs._1; + } + return fromArray(arr); +} + +function map4(f, ws, xs, ys, zs) +{ + var arr = []; + while ( ws.ctor !== '[]' + && xs.ctor !== '[]' + && ys.ctor !== '[]' + && zs.ctor !== '[]') + { + arr.push(A4(f, ws._0, xs._0, ys._0, zs._0)); + ws = ws._1; + xs = xs._1; + ys = ys._1; + zs = zs._1; + } + return fromArray(arr); +} + +function map5(f, vs, ws, xs, ys, zs) +{ + var arr = []; + while ( vs.ctor !== '[]' + && ws.ctor !== '[]' + && xs.ctor !== '[]' + && ys.ctor !== '[]' + && zs.ctor !== '[]') + { + arr.push(A5(f, vs._0, ws._0, xs._0, ys._0, zs._0)); + vs = vs._1; + ws = ws._1; + xs = xs._1; + ys = ys._1; + zs = zs._1; + } + return fromArray(arr); +} + +function sortBy(f, xs) +{ + return fromArray(toArray(xs).sort(function(a, b) { + return _elm_lang$core$Native_Utils.cmp(f(a), f(b)); + })); +} + +function sortWith(f, xs) +{ + return fromArray(toArray(xs).sort(function(a, b) { + var ord = f(a)(b).ctor; + return ord === 'EQ' ? 0 : ord === 'LT' ? -1 : 1; + })); +} + +return { + Nil: Nil, + Cons: Cons, + cons: F2(Cons), + toArray: toArray, + fromArray: fromArray, + + foldr: F3(foldr), + + map2: F3(map2), + map3: F4(map3), + map4: F5(map4), + map5: F6(map5), + sortBy: F2(sortBy), + sortWith: F2(sortWith) +}; + +}(); \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Platform.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Platform.js new file mode 100644 index 0000000..bd6da19 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Platform.js @@ -0,0 +1,559 @@ +//import // + +var _elm_lang$core$Native_Platform = function() { + + +// PROGRAMS + +function program(impl) +{ + return function(flagDecoder) + { + return function(object, moduleName) + { + object['worker'] = function worker(flags) + { + if (typeof flags !== 'undefined') + { + throw new Error( + 'The `' + moduleName + '` module does not need flags.\n' + + 'Call ' + moduleName + '.worker() with no arguments and you should be all set!' + ); + } + + return initialize( + impl.init, + impl.update, + impl.subscriptions, + renderer + ); + }; + }; + }; +} + +function programWithFlags(impl) +{ + return function(flagDecoder) + { + return function(object, moduleName) + { + object['worker'] = function worker(flags) + { + if (typeof flagDecoder === 'undefined') + { + throw new Error( + 'Are you trying to sneak a Never value into Elm? Trickster!\n' + + 'It looks like ' + moduleName + '.main is defined with `programWithFlags` but has type `Program Never`.\n' + + 'Use `program` instead if you do not want flags.' + ); + } + + var result = A2(_elm_lang$core$Native_Json.run, flagDecoder, flags); + if (result.ctor === 'Err') + { + throw new Error( + moduleName + '.worker(...) was called with an unexpected argument.\n' + + 'I tried to convert it to an Elm value, but ran into this problem:\n\n' + + result._0 + ); + } + + return initialize( + impl.init(result._0), + impl.update, + impl.subscriptions, + renderer + ); + }; + }; + }; +} + +function renderer(enqueue, _) +{ + return function(_) {}; +} + + +// HTML TO PROGRAM + +function htmlToProgram(vnode) +{ + var emptyBag = batch(_elm_lang$core$Native_List.Nil); + var noChange = _elm_lang$core$Native_Utils.Tuple2( + _elm_lang$core$Native_Utils.Tuple0, + emptyBag + ); + + return _elm_lang$virtual_dom$VirtualDom$program({ + init: noChange, + view: function(model) { return main; }, + update: F2(function(msg, model) { return noChange; }), + subscriptions: function (model) { return emptyBag; } + }); +} + + +// INITIALIZE A PROGRAM + +function initialize(init, update, subscriptions, renderer) +{ + // ambient state + var managers = {}; + var updateView; + + // init and update state in main process + var initApp = _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) { + var model = init._0; + updateView = renderer(enqueue, model); + var cmds = init._1; + var subs = subscriptions(model); + dispatchEffects(managers, cmds, subs); + callback(_elm_lang$core$Native_Scheduler.succeed(model)); + }); + + function onMessage(msg, model) + { + return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) { + var results = A2(update, msg, model); + model = results._0; + updateView(model); + var cmds = results._1; + var subs = subscriptions(model); + dispatchEffects(managers, cmds, subs); + callback(_elm_lang$core$Native_Scheduler.succeed(model)); + }); + } + + var mainProcess = spawnLoop(initApp, onMessage); + + function enqueue(msg) + { + _elm_lang$core$Native_Scheduler.rawSend(mainProcess, msg); + } + + var ports = setupEffects(managers, enqueue); + + return ports ? { ports: ports } : {}; +} + + +// EFFECT MANAGERS + +var effectManagers = {}; + +function setupEffects(managers, callback) +{ + var ports; + + // setup all necessary effect managers + for (var key in effectManagers) + { + var manager = effectManagers[key]; + + if (manager.isForeign) + { + ports = ports || {}; + ports[key] = manager.tag === 'cmd' + ? setupOutgoingPort(key) + : setupIncomingPort(key, callback); + } + + managers[key] = makeManager(manager, callback); + } + + return ports; +} + +function makeManager(info, callback) +{ + var router = { + main: callback, + self: undefined + }; + + var tag = info.tag; + var onEffects = info.onEffects; + var onSelfMsg = info.onSelfMsg; + + function onMessage(msg, state) + { + if (msg.ctor === 'self') + { + return A3(onSelfMsg, router, msg._0, state); + } + + var fx = msg._0; + switch (tag) + { + case 'cmd': + return A3(onEffects, router, fx.cmds, state); + + case 'sub': + return A3(onEffects, router, fx.subs, state); + + case 'fx': + return A4(onEffects, router, fx.cmds, fx.subs, state); + } + } + + var process = spawnLoop(info.init, onMessage); + router.self = process; + return process; +} + +function sendToApp(router, msg) +{ + return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) + { + router.main(msg); + callback(_elm_lang$core$Native_Scheduler.succeed(_elm_lang$core$Native_Utils.Tuple0)); + }); +} + +function sendToSelf(router, msg) +{ + return A2(_elm_lang$core$Native_Scheduler.send, router.self, { + ctor: 'self', + _0: msg + }); +} + + +// HELPER for STATEFUL LOOPS + +function spawnLoop(init, onMessage) +{ + var andThen = _elm_lang$core$Native_Scheduler.andThen; + + function loop(state) + { + var handleMsg = _elm_lang$core$Native_Scheduler.receive(function(msg) { + return onMessage(msg, state); + }); + return A2(andThen, loop, handleMsg); + } + + var task = A2(andThen, loop, init); + + return _elm_lang$core$Native_Scheduler.rawSpawn(task); +} + + +// BAGS + +function leaf(home) +{ + return function(value) + { + return { + type: 'leaf', + home: home, + value: value + }; + }; +} + +function batch(list) +{ + return { + type: 'node', + branches: list + }; +} + +function map(tagger, bag) +{ + return { + type: 'map', + tagger: tagger, + tree: bag + } +} + + +// PIPE BAGS INTO EFFECT MANAGERS + +function dispatchEffects(managers, cmdBag, subBag) +{ + var effectsDict = {}; + gatherEffects(true, cmdBag, effectsDict, null); + gatherEffects(false, subBag, effectsDict, null); + + for (var home in managers) + { + var fx = home in effectsDict + ? effectsDict[home] + : { + cmds: _elm_lang$core$Native_List.Nil, + subs: _elm_lang$core$Native_List.Nil + }; + + _elm_lang$core$Native_Scheduler.rawSend(managers[home], { ctor: 'fx', _0: fx }); + } +} + +function gatherEffects(isCmd, bag, effectsDict, taggers) +{ + switch (bag.type) + { + case 'leaf': + var home = bag.home; + var effect = toEffect(isCmd, home, taggers, bag.value); + effectsDict[home] = insert(isCmd, effect, effectsDict[home]); + return; + + case 'node': + var list = bag.branches; + while (list.ctor !== '[]') + { + gatherEffects(isCmd, list._0, effectsDict, taggers); + list = list._1; + } + return; + + case 'map': + gatherEffects(isCmd, bag.tree, effectsDict, { + tagger: bag.tagger, + rest: taggers + }); + return; + } +} + +function toEffect(isCmd, home, taggers, value) +{ + function applyTaggers(x) + { + var temp = taggers; + while (temp) + { + x = temp.tagger(x); + temp = temp.rest; + } + return x; + } + + var map = isCmd + ? effectManagers[home].cmdMap + : effectManagers[home].subMap; + + return A2(map, applyTaggers, value) +} + +function insert(isCmd, newEffect, effects) +{ + effects = effects || { + cmds: _elm_lang$core$Native_List.Nil, + subs: _elm_lang$core$Native_List.Nil + }; + if (isCmd) + { + effects.cmds = _elm_lang$core$Native_List.Cons(newEffect, effects.cmds); + return effects; + } + effects.subs = _elm_lang$core$Native_List.Cons(newEffect, effects.subs); + return effects; +} + + +// PORTS + +function checkPortName(name) +{ + if (name in effectManagers) + { + throw new Error('There can only be one port named `' + name + '`, but your program has multiple.'); + } +} + + +// OUTGOING PORTS + +function outgoingPort(name, converter) +{ + checkPortName(name); + effectManagers[name] = { + tag: 'cmd', + cmdMap: outgoingPortMap, + converter: converter, + isForeign: true + }; + return leaf(name); +} + +var outgoingPortMap = F2(function cmdMap(tagger, value) { + return value; +}); + +function setupOutgoingPort(name) +{ + var subs = []; + var converter = effectManagers[name].converter; + + // CREATE MANAGER + + var init = _elm_lang$core$Native_Scheduler.succeed(null); + + function onEffects(router, cmdList, state) + { + while (cmdList.ctor !== '[]') + { + // grab a separate reference to subs in case unsubscribe is called + var currentSubs = subs; + var value = converter(cmdList._0); + for (var i = 0; i < currentSubs.length; i++) + { + currentSubs[i](value); + } + cmdList = cmdList._1; + } + return init; + } + + effectManagers[name].init = init; + effectManagers[name].onEffects = F3(onEffects); + + // PUBLIC API + + function subscribe(callback) + { + subs.push(callback); + } + + function unsubscribe(callback) + { + // copy subs into a new array in case unsubscribe is called within a + // subscribed callback + subs = subs.slice(); + var index = subs.indexOf(callback); + if (index >= 0) + { + subs.splice(index, 1); + } + } + + return { + subscribe: subscribe, + unsubscribe: unsubscribe + }; +} + + +// INCOMING PORTS + +function incomingPort(name, converter) +{ + checkPortName(name); + effectManagers[name] = { + tag: 'sub', + subMap: incomingPortMap, + converter: converter, + isForeign: true + }; + return leaf(name); +} + +var incomingPortMap = F2(function subMap(tagger, finalTagger) +{ + return function(value) + { + return tagger(finalTagger(value)); + }; +}); + +function setupIncomingPort(name, callback) +{ + var sentBeforeInit = []; + var subs = _elm_lang$core$Native_List.Nil; + var converter = effectManagers[name].converter; + var currentOnEffects = preInitOnEffects; + var currentSend = preInitSend; + + // CREATE MANAGER + + var init = _elm_lang$core$Native_Scheduler.succeed(null); + + function preInitOnEffects(router, subList, state) + { + var postInitResult = postInitOnEffects(router, subList, state); + + for(var i = 0; i < sentBeforeInit.length; i++) + { + postInitSend(sentBeforeInit[i]); + } + + sentBeforeInit = null; // to release objects held in queue + currentSend = postInitSend; + currentOnEffects = postInitOnEffects; + return postInitResult; + } + + function postInitOnEffects(router, subList, state) + { + subs = subList; + return init; + } + + function onEffects(router, subList, state) + { + return currentOnEffects(router, subList, state); + } + + effectManagers[name].init = init; + effectManagers[name].onEffects = F3(onEffects); + + // PUBLIC API + + function preInitSend(value) + { + sentBeforeInit.push(value); + } + + function postInitSend(value) + { + var temp = subs; + while (temp.ctor !== '[]') + { + callback(temp._0(value)); + temp = temp._1; + } + } + + function send(incomingValue) + { + var result = A2(_elm_lang$core$Json_Decode$decodeValue, converter, incomingValue); + if (result.ctor === 'Err') + { + throw new Error('Trying to send an unexpected type of value through port `' + name + '`:\n' + result._0); + } + + currentSend(result._0); + } + + return { send: send }; +} + +return { + // routers + sendToApp: F2(sendToApp), + sendToSelf: F2(sendToSelf), + + // global setup + effectManagers: effectManagers, + outgoingPort: outgoingPort, + incomingPort: incomingPort, + + htmlToProgram: htmlToProgram, + program: program, + programWithFlags: programWithFlags, + initialize: initialize, + + // effect bags + leaf: leaf, + batch: batch, + map: F2(map) +}; + +}(); diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Regex.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Regex.js new file mode 100644 index 0000000..d3cc0dd --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Regex.js @@ -0,0 +1,119 @@ +//import Maybe, Native.List // + +var _elm_lang$core$Native_Regex = function() { + +function escape(str) +{ + return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); +} +function caseInsensitive(re) +{ + return new RegExp(re.source, 'gi'); +} +function regex(raw) +{ + return new RegExp(raw, 'g'); +} + +function contains(re, string) +{ + return string.match(re) !== null; +} + +function find(n, re, str) +{ + n = n.ctor === 'All' ? Infinity : n._0; + var out = []; + var number = 0; + var string = str; + var lastIndex = re.lastIndex; + var prevLastIndex = -1; + var result; + while (number++ < n && (result = re.exec(string))) + { + if (prevLastIndex === re.lastIndex) break; + var i = result.length - 1; + var subs = new Array(i); + while (i > 0) + { + var submatch = result[i]; + subs[--i] = submatch === undefined + ? _elm_lang$core$Maybe$Nothing + : _elm_lang$core$Maybe$Just(submatch); + } + out.push({ + match: result[0], + submatches: _elm_lang$core$Native_List.fromArray(subs), + index: result.index, + number: number + }); + prevLastIndex = re.lastIndex; + } + re.lastIndex = lastIndex; + return _elm_lang$core$Native_List.fromArray(out); +} + +function replace(n, re, replacer, string) +{ + n = n.ctor === 'All' ? Infinity : n._0; + var count = 0; + function jsReplacer(match) + { + if (count++ >= n) + { + return match; + } + var i = arguments.length - 3; + var submatches = new Array(i); + while (i > 0) + { + var submatch = arguments[i]; + submatches[--i] = submatch === undefined + ? _elm_lang$core$Maybe$Nothing + : _elm_lang$core$Maybe$Just(submatch); + } + return replacer({ + match: match, + submatches: _elm_lang$core$Native_List.fromArray(submatches), + index: arguments[arguments.length - 2], + number: count + }); + } + return string.replace(re, jsReplacer); +} + +function split(n, re, str) +{ + n = n.ctor === 'All' ? Infinity : n._0; + if (n === Infinity) + { + return _elm_lang$core$Native_List.fromArray(str.split(re)); + } + var string = str; + var result; + var out = []; + var start = re.lastIndex; + var restoreLastIndex = re.lastIndex; + while (n--) + { + if (!(result = re.exec(string))) break; + out.push(string.slice(start, result.index)); + start = re.lastIndex; + } + out.push(string.slice(start)); + re.lastIndex = restoreLastIndex; + return _elm_lang$core$Native_List.fromArray(out); +} + +return { + regex: regex, + caseInsensitive: caseInsensitive, + escape: escape, + + contains: F2(contains), + find: F3(find), + replace: F4(replace), + split: F3(split) +}; + +}(); diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Scheduler.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Scheduler.js new file mode 100644 index 0000000..00f8259 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Scheduler.js @@ -0,0 +1,281 @@ +//import Native.Utils // + +var _elm_lang$core$Native_Scheduler = function() { + +var MAX_STEPS = 10000; + + +// TASKS + +function succeed(value) +{ + return { + ctor: '_Task_succeed', + value: value + }; +} + +function fail(error) +{ + return { + ctor: '_Task_fail', + value: error + }; +} + +function nativeBinding(callback) +{ + return { + ctor: '_Task_nativeBinding', + callback: callback, + cancel: null + }; +} + +function andThen(callback, task) +{ + return { + ctor: '_Task_andThen', + callback: callback, + task: task + }; +} + +function onError(callback, task) +{ + return { + ctor: '_Task_onError', + callback: callback, + task: task + }; +} + +function receive(callback) +{ + return { + ctor: '_Task_receive', + callback: callback + }; +} + + +// PROCESSES + +function rawSpawn(task) +{ + var process = { + ctor: '_Process', + id: _elm_lang$core$Native_Utils.guid(), + root: task, + stack: null, + mailbox: [] + }; + + enqueue(process); + + return process; +} + +function spawn(task) +{ + return nativeBinding(function(callback) { + var process = rawSpawn(task); + callback(succeed(process)); + }); +} + +function rawSend(process, msg) +{ + process.mailbox.push(msg); + enqueue(process); +} + +function send(process, msg) +{ + return nativeBinding(function(callback) { + rawSend(process, msg); + callback(succeed(_elm_lang$core$Native_Utils.Tuple0)); + }); +} + +function kill(process) +{ + return nativeBinding(function(callback) { + var root = process.root; + if (root.ctor === '_Task_nativeBinding' && root.cancel) + { + root.cancel(); + } + + process.root = null; + + callback(succeed(_elm_lang$core$Native_Utils.Tuple0)); + }); +} + +function sleep(time) +{ + return nativeBinding(function(callback) { + var id = setTimeout(function() { + callback(succeed(_elm_lang$core$Native_Utils.Tuple0)); + }, time); + + return function() { clearTimeout(id); }; + }); +} + + +// STEP PROCESSES + +function step(numSteps, process) +{ + while (numSteps < MAX_STEPS) + { + var ctor = process.root.ctor; + + if (ctor === '_Task_succeed') + { + while (process.stack && process.stack.ctor === '_Task_onError') + { + process.stack = process.stack.rest; + } + if (process.stack === null) + { + break; + } + process.root = process.stack.callback(process.root.value); + process.stack = process.stack.rest; + ++numSteps; + continue; + } + + if (ctor === '_Task_fail') + { + while (process.stack && process.stack.ctor === '_Task_andThen') + { + process.stack = process.stack.rest; + } + if (process.stack === null) + { + break; + } + process.root = process.stack.callback(process.root.value); + process.stack = process.stack.rest; + ++numSteps; + continue; + } + + if (ctor === '_Task_andThen') + { + process.stack = { + ctor: '_Task_andThen', + callback: process.root.callback, + rest: process.stack + }; + process.root = process.root.task; + ++numSteps; + continue; + } + + if (ctor === '_Task_onError') + { + process.stack = { + ctor: '_Task_onError', + callback: process.root.callback, + rest: process.stack + }; + process.root = process.root.task; + ++numSteps; + continue; + } + + if (ctor === '_Task_nativeBinding') + { + process.root.cancel = process.root.callback(function(newRoot) { + process.root = newRoot; + enqueue(process); + }); + + break; + } + + if (ctor === '_Task_receive') + { + var mailbox = process.mailbox; + if (mailbox.length === 0) + { + break; + } + + process.root = process.root.callback(mailbox.shift()); + ++numSteps; + continue; + } + + throw new Error(ctor); + } + + if (numSteps < MAX_STEPS) + { + return numSteps + 1; + } + enqueue(process); + + return numSteps; +} + + +// WORK QUEUE + +var working = false; +var workQueue = []; + +function enqueue(process) +{ + workQueue.push(process); + + if (!working) + { + setTimeout(work, 0); + working = true; + } +} + +function work() +{ + var numSteps = 0; + var process; + while (numSteps < MAX_STEPS && (process = workQueue.shift())) + { + if (process.root) + { + numSteps = step(numSteps, process); + } + } + if (!process) + { + working = false; + return; + } + setTimeout(work, 0); +} + + +return { + succeed: succeed, + fail: fail, + nativeBinding: nativeBinding, + andThen: F2(andThen), + onError: F2(onError), + receive: receive, + + spawn: spawn, + kill: kill, + sleep: sleep, + send: F2(send), + + rawSpawn: rawSpawn, + rawSend: rawSend +}; + +}(); \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/String.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/String.js new file mode 100644 index 0000000..3a21c76 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/String.js @@ -0,0 +1,339 @@ +//import Maybe, Native.List, Native.Utils, Result // + +var _elm_lang$core$Native_String = function() { + +function isEmpty(str) +{ + return str.length === 0; +} +function cons(chr, str) +{ + return chr + str; +} +function uncons(str) +{ + var hd = str[0]; + if (hd) + { + return _elm_lang$core$Maybe$Just(_elm_lang$core$Native_Utils.Tuple2(_elm_lang$core$Native_Utils.chr(hd), str.slice(1))); + } + return _elm_lang$core$Maybe$Nothing; +} +function append(a, b) +{ + return a + b; +} +function concat(strs) +{ + return _elm_lang$core$Native_List.toArray(strs).join(''); +} +function length(str) +{ + return str.length; +} +function map(f, str) +{ + var out = str.split(''); + for (var i = out.length; i--; ) + { + out[i] = f(_elm_lang$core$Native_Utils.chr(out[i])); + } + return out.join(''); +} +function filter(pred, str) +{ + return str.split('').map(_elm_lang$core$Native_Utils.chr).filter(pred).join(''); +} +function reverse(str) +{ + return str.split('').reverse().join(''); +} +function foldl(f, b, str) +{ + var len = str.length; + for (var i = 0; i < len; ++i) + { + b = A2(f, _elm_lang$core$Native_Utils.chr(str[i]), b); + } + return b; +} +function foldr(f, b, str) +{ + for (var i = str.length; i--; ) + { + b = A2(f, _elm_lang$core$Native_Utils.chr(str[i]), b); + } + return b; +} +function split(sep, str) +{ + return _elm_lang$core$Native_List.fromArray(str.split(sep)); +} +function join(sep, strs) +{ + return _elm_lang$core$Native_List.toArray(strs).join(sep); +} +function repeat(n, str) +{ + var result = ''; + while (n > 0) + { + if (n & 1) + { + result += str; + } + n >>= 1, str += str; + } + return result; +} +function slice(start, end, str) +{ + return str.slice(start, end); +} +function left(n, str) +{ + return n < 1 ? '' : str.slice(0, n); +} +function right(n, str) +{ + return n < 1 ? '' : str.slice(-n); +} +function dropLeft(n, str) +{ + return n < 1 ? str : str.slice(n); +} +function dropRight(n, str) +{ + return n < 1 ? str : str.slice(0, -n); +} +function pad(n, chr, str) +{ + var half = (n - str.length) / 2; + return repeat(Math.ceil(half), chr) + str + repeat(half | 0, chr); +} +function padRight(n, chr, str) +{ + return str + repeat(n - str.length, chr); +} +function padLeft(n, chr, str) +{ + return repeat(n - str.length, chr) + str; +} + +function trim(str) +{ + return str.trim(); +} +function trimLeft(str) +{ + return str.replace(/^\s+/, ''); +} +function trimRight(str) +{ + return str.replace(/\s+$/, ''); +} + +function words(str) +{ + return _elm_lang$core$Native_List.fromArray(str.trim().split(/\s+/g)); +} +function lines(str) +{ + return _elm_lang$core$Native_List.fromArray(str.split(/\r\n|\r|\n/g)); +} + +function toUpper(str) +{ + return str.toUpperCase(); +} +function toLower(str) +{ + return str.toLowerCase(); +} + +function any(pred, str) +{ + for (var i = str.length; i--; ) + { + if (pred(_elm_lang$core$Native_Utils.chr(str[i]))) + { + return true; + } + } + return false; +} +function all(pred, str) +{ + for (var i = str.length; i--; ) + { + if (!pred(_elm_lang$core$Native_Utils.chr(str[i]))) + { + return false; + } + } + return true; +} + +function contains(sub, str) +{ + return str.indexOf(sub) > -1; +} +function startsWith(sub, str) +{ + return str.indexOf(sub) === 0; +} +function endsWith(sub, str) +{ + return str.length >= sub.length && + str.lastIndexOf(sub) === str.length - sub.length; +} +function indexes(sub, str) +{ + var subLen = sub.length; + + if (subLen < 1) + { + return _elm_lang$core$Native_List.Nil; + } + + var i = 0; + var is = []; + + while ((i = str.indexOf(sub, i)) > -1) + { + is.push(i); + i = i + subLen; + } + + return _elm_lang$core$Native_List.fromArray(is); +} + + +function toInt(s) +{ + var len = s.length; + + // if empty + if (len === 0) + { + return intErr(s); + } + + // if hex + var c = s[0]; + if (c === '0' && s[1] === 'x') + { + for (var i = 2; i < len; ++i) + { + var c = s[i]; + if (('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')) + { + continue; + } + return intErr(s); + } + return _elm_lang$core$Result$Ok(parseInt(s, 16)); + } + + // is decimal + if (c > '9' || (c < '0' && c !== '-' && c !== '+')) + { + return intErr(s); + } + for (var i = 1; i < len; ++i) + { + var c = s[i]; + if (c < '0' || '9' < c) + { + return intErr(s); + } + } + + return _elm_lang$core$Result$Ok(parseInt(s, 10)); +} + +function intErr(s) +{ + return _elm_lang$core$Result$Err("could not convert string '" + s + "' to an Int"); +} + + +function toFloat(s) +{ + // check if it is a hex, octal, or binary number + if (s.length === 0 || /[\sxbo]/.test(s)) + { + return floatErr(s); + } + var n = +s; + // faster isNaN check + return n === n ? _elm_lang$core$Result$Ok(n) : floatErr(s); +} + +function floatErr(s) +{ + return _elm_lang$core$Result$Err("could not convert string '" + s + "' to a Float"); +} + + +function toList(str) +{ + return _elm_lang$core$Native_List.fromArray(str.split('').map(_elm_lang$core$Native_Utils.chr)); +} +function fromList(chars) +{ + return _elm_lang$core$Native_List.toArray(chars).join(''); +} + +return { + isEmpty: isEmpty, + cons: F2(cons), + uncons: uncons, + append: F2(append), + concat: concat, + length: length, + map: F2(map), + filter: F2(filter), + reverse: reverse, + foldl: F3(foldl), + foldr: F3(foldr), + + split: F2(split), + join: F2(join), + repeat: F2(repeat), + + slice: F3(slice), + left: F2(left), + right: F2(right), + dropLeft: F2(dropLeft), + dropRight: F2(dropRight), + + pad: F3(pad), + padLeft: F3(padLeft), + padRight: F3(padRight), + + trim: trim, + trimLeft: trimLeft, + trimRight: trimRight, + + words: words, + lines: lines, + + toUpper: toUpper, + toLower: toLower, + + any: F2(any), + all: F2(all), + + contains: F2(contains), + startsWith: F2(startsWith), + endsWith: F2(endsWith), + indexes: F2(indexes), + + toInt: toInt, + toFloat: toFloat, + toList: toList, + fromList: fromList +}; + +}(); diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Time.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Time.js new file mode 100644 index 0000000..6b665ea --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Time.js @@ -0,0 +1,27 @@ +//import Native.Scheduler // + +var _elm_lang$core$Native_Time = function() { + +var now = _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) +{ + callback(_elm_lang$core$Native_Scheduler.succeed(Date.now())); +}); + +function setInterval_(interval, task) +{ + return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) + { + var id = setInterval(function() { + _elm_lang$core$Native_Scheduler.rawSpawn(task); + }, interval); + + return function() { clearInterval(id); }; + }); +} + +return { + now: now, + setInterval_: F2(setInterval_) +}; + +}(); \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Utils.js b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Utils.js new file mode 100644 index 0000000..20aed5f --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Native/Utils.js @@ -0,0 +1,488 @@ +//import // + +var _elm_lang$core$Native_Utils = function() { + +// COMPARISONS + +function eq(x, y) +{ + var stack = []; + var isEqual = eqHelp(x, y, 0, stack); + var pair; + while (isEqual && (pair = stack.pop())) + { + isEqual = eqHelp(pair.x, pair.y, 0, stack); + } + return isEqual; +} + + +function eqHelp(x, y, depth, stack) +{ + if (depth > 100) + { + stack.push({ x: x, y: y }); + return true; + } + + if (x === y) + { + return true; + } + + if (typeof x !== 'object') + { + if (typeof x === 'function') + { + throw new Error( + 'Trying to use `(==)` on functions. There is no way to know if functions are "the same" in the Elm sense.' + + ' Read more about this at http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#==' + + ' which describes why it is this way and what the better version will look like.' + ); + } + return false; + } + + if (x === null || y === null) + { + return false + } + + if (x instanceof Date) + { + return x.getTime() === y.getTime(); + } + + if (!('ctor' in x)) + { + for (var key in x) + { + if (!eqHelp(x[key], y[key], depth + 1, stack)) + { + return false; + } + } + return true; + } + + // convert Dicts and Sets to lists + if (x.ctor === 'RBNode_elm_builtin' || x.ctor === 'RBEmpty_elm_builtin') + { + x = _elm_lang$core$Dict$toList(x); + y = _elm_lang$core$Dict$toList(y); + } + if (x.ctor === 'Set_elm_builtin') + { + x = _elm_lang$core$Set$toList(x); + y = _elm_lang$core$Set$toList(y); + } + + // check if lists are equal without recursion + if (x.ctor === '::') + { + var a = x; + var b = y; + while (a.ctor === '::' && b.ctor === '::') + { + if (!eqHelp(a._0, b._0, depth + 1, stack)) + { + return false; + } + a = a._1; + b = b._1; + } + return a.ctor === b.ctor; + } + + // check if Arrays are equal + if (x.ctor === '_Array') + { + var xs = _elm_lang$core$Native_Array.toJSArray(x); + var ys = _elm_lang$core$Native_Array.toJSArray(y); + if (xs.length !== ys.length) + { + return false; + } + for (var i = 0; i < xs.length; i++) + { + if (!eqHelp(xs[i], ys[i], depth + 1, stack)) + { + return false; + } + } + return true; + } + + if (!eqHelp(x.ctor, y.ctor, depth + 1, stack)) + { + return false; + } + + for (var key in x) + { + if (!eqHelp(x[key], y[key], depth + 1, stack)) + { + return false; + } + } + return true; +} + +// Code in Generate/JavaScript.hs, Basics.js, and List.js depends on +// the particular integer values assigned to LT, EQ, and GT. + +var LT = -1, EQ = 0, GT = 1; + +function cmp(x, y) +{ + if (typeof x !== 'object') + { + return x === y ? EQ : x < y ? LT : GT; + } + + if (x instanceof String) + { + var a = x.valueOf(); + var b = y.valueOf(); + return a === b ? EQ : a < b ? LT : GT; + } + + if (x.ctor === '::' || x.ctor === '[]') + { + while (x.ctor === '::' && y.ctor === '::') + { + var ord = cmp(x._0, y._0); + if (ord !== EQ) + { + return ord; + } + x = x._1; + y = y._1; + } + return x.ctor === y.ctor ? EQ : x.ctor === '[]' ? LT : GT; + } + + if (x.ctor.slice(0, 6) === '_Tuple') + { + var ord; + var n = x.ctor.slice(6) - 0; + var err = 'cannot compare tuples with more than 6 elements.'; + if (n === 0) return EQ; + if (n >= 1) { ord = cmp(x._0, y._0); if (ord !== EQ) return ord; + if (n >= 2) { ord = cmp(x._1, y._1); if (ord !== EQ) return ord; + if (n >= 3) { ord = cmp(x._2, y._2); if (ord !== EQ) return ord; + if (n >= 4) { ord = cmp(x._3, y._3); if (ord !== EQ) return ord; + if (n >= 5) { ord = cmp(x._4, y._4); if (ord !== EQ) return ord; + if (n >= 6) { ord = cmp(x._5, y._5); if (ord !== EQ) return ord; + if (n >= 7) throw new Error('Comparison error: ' + err); } } } } } } + return EQ; + } + + throw new Error( + 'Comparison error: comparison is only defined on ints, ' + + 'floats, times, chars, strings, lists of comparable values, ' + + 'and tuples of comparable values.' + ); +} + + +// COMMON VALUES + +var Tuple0 = { + ctor: '_Tuple0' +}; + +function Tuple2(x, y) +{ + return { + ctor: '_Tuple2', + _0: x, + _1: y + }; +} + +function chr(c) +{ + return new String(c); +} + + +// GUID + +var count = 0; +function guid(_) +{ + return count++; +} + + +// RECORDS + +function update(oldRecord, updatedFields) +{ + var newRecord = {}; + + for (var key in oldRecord) + { + newRecord[key] = oldRecord[key]; + } + + for (var key in updatedFields) + { + newRecord[key] = updatedFields[key]; + } + + return newRecord; +} + + +//// LIST STUFF //// + +var Nil = { ctor: '[]' }; + +function Cons(hd, tl) +{ + return { + ctor: '::', + _0: hd, + _1: tl + }; +} + +function append(xs, ys) +{ + // append Strings + if (typeof xs === 'string') + { + return xs + ys; + } + + // append Lists + if (xs.ctor === '[]') + { + return ys; + } + var root = Cons(xs._0, Nil); + var curr = root; + xs = xs._1; + while (xs.ctor !== '[]') + { + curr._1 = Cons(xs._0, Nil); + xs = xs._1; + curr = curr._1; + } + curr._1 = ys; + return root; +} + + +// CRASHES + +function crash(moduleName, region) +{ + return function(message) { + throw new Error( + 'Ran into a `Debug.crash` in module `' + moduleName + '` ' + regionToString(region) + '\n' + + 'The message provided by the code author is:\n\n ' + + message + ); + }; +} + +function crashCase(moduleName, region, value) +{ + return function(message) { + throw new Error( + 'Ran into a `Debug.crash` in module `' + moduleName + '`\n\n' + + 'This was caused by the `case` expression ' + regionToString(region) + '.\n' + + 'One of the branches ended with a crash and the following value got through:\n\n ' + toString(value) + '\n\n' + + 'The message provided by the code author is:\n\n ' + + message + ); + }; +} + +function regionToString(region) +{ + if (region.start.line == region.end.line) + { + return 'on line ' + region.start.line; + } + return 'between lines ' + region.start.line + ' and ' + region.end.line; +} + + +// TO STRING + +function toString(v) +{ + var type = typeof v; + if (type === 'function') + { + return ''; + } + + if (type === 'boolean') + { + return v ? 'True' : 'False'; + } + + if (type === 'number') + { + return v + ''; + } + + if (v instanceof String) + { + return '\'' + addSlashes(v, true) + '\''; + } + + if (type === 'string') + { + return '"' + addSlashes(v, false) + '"'; + } + + if (v === null) + { + return 'null'; + } + + if (type === 'object' && 'ctor' in v) + { + var ctorStarter = v.ctor.substring(0, 5); + + if (ctorStarter === '_Tupl') + { + var output = []; + for (var k in v) + { + if (k === 'ctor') continue; + output.push(toString(v[k])); + } + return '(' + output.join(',') + ')'; + } + + if (ctorStarter === '_Task') + { + return '' + } + + if (v.ctor === '_Array') + { + var list = _elm_lang$core$Array$toList(v); + return 'Array.fromList ' + toString(list); + } + + if (v.ctor === '') + { + return ''; + } + + if (v.ctor === '_Process') + { + return ''; + } + + if (v.ctor === '::') + { + var output = '[' + toString(v._0); + v = v._1; + while (v.ctor === '::') + { + output += ',' + toString(v._0); + v = v._1; + } + return output + ']'; + } + + if (v.ctor === '[]') + { + return '[]'; + } + + if (v.ctor === 'Set_elm_builtin') + { + return 'Set.fromList ' + toString(_elm_lang$core$Set$toList(v)); + } + + if (v.ctor === 'RBNode_elm_builtin' || v.ctor === 'RBEmpty_elm_builtin') + { + return 'Dict.fromList ' + toString(_elm_lang$core$Dict$toList(v)); + } + + var output = ''; + for (var i in v) + { + if (i === 'ctor') continue; + var str = toString(v[i]); + var c0 = str[0]; + var parenless = c0 === '{' || c0 === '(' || c0 === '<' || c0 === '"' || str.indexOf(' ') < 0; + output += ' ' + (parenless ? str : '(' + str + ')'); + } + return v.ctor + output; + } + + if (type === 'object') + { + if (v instanceof Date) + { + return '<' + v.toString() + '>'; + } + + if (v.elm_web_socket) + { + return ''; + } + + var output = []; + for (var k in v) + { + output.push(k + ' = ' + toString(v[k])); + } + if (output.length === 0) + { + return '{}'; + } + return '{ ' + output.join(', ') + ' }'; + } + + return ''; +} + +function addSlashes(str, isChar) +{ + var s = str.replace(/\\/g, '\\\\') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + .replace(/\r/g, '\\r') + .replace(/\v/g, '\\v') + .replace(/\0/g, '\\0'); + if (isChar) + { + return s.replace(/\'/g, '\\\''); + } + else + { + return s.replace(/\"/g, '\\"'); + } +} + + +return { + eq: eq, + cmp: cmp, + Tuple0: Tuple0, + Tuple2: Tuple2, + chr: chr, + update: update, + guid: guid, + + append: F2(append), + + crash: crash, + crashCase: crashCase, + + toString: toString +}; + +}(); \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform.elm new file mode 100644 index 0000000..2a136cc --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform.elm @@ -0,0 +1,145 @@ +module Platform exposing + ( Program, program, programWithFlags + , Task, ProcessId + , Router, sendToApp, sendToSelf + ) + +{-| + +# Programs +@docs Program, program, programWithFlags + +# Platform Internals + +## Tasks and Processes +@docs Task, ProcessId + +## Effect Manager Helpers + +An extremely tiny portion of library authors should ever write effect managers. +Fundamentally, Elm needs maybe 10 of them total. I get that people are smart, +curious, etc. but that is not a substitute for a legitimate reason to make an +effect manager. Do you have an *organic need* this fills? Or are you just +curious? Public discussions of your explorations should be framed accordingly. + +@docs Router, sendToApp, sendToSelf +-} + +import Basics exposing (Never) +import Native.Platform +import Native.Scheduler +import Platform.Cmd exposing (Cmd) +import Platform.Sub exposing (Sub) + + + +-- PROGRAMS + + +{-| A `Program` describes how to manage your Elm app. + +You can create [headless][] programs with the [`program`](#program) and +[`programWithFlags`](#programWithFlags) functions. Similar functions exist in +[`Html`][html] that let you specify a view. + +[headless]: https://en.wikipedia.org/wiki/Headless_software +[html]: http://package.elm-lang.org/packages/elm-lang/html/latest/Html + +Honestly, it is totally normal if this seems crazy at first. The best way to +understand is to work through [guide.elm-lang.org](http://guide.elm-lang.org/). +It makes way more sense in context! +-} +type Program flags model msg = Program + + +{-| Create a [headless][] program. This is great if you want to use Elm as the +“brain” for something else. You can still communicate with JS via +ports and manage your model, you just do not have to specify a `view`. + +[headless]: https://en.wikipedia.org/wiki/Headless_software + +Initializing a headless program from JavaScript looks like this: + +```javascript +var app = Elm.MyThing.worker(); +``` +-} +program + : { init : (model, Cmd msg) + , update : msg -> model -> (model, Cmd msg) + , subscriptions : model -> Sub msg + } + -> Program Never model msg +program = + Native.Platform.program + + +{-| Same as [`program`](#program), but you can provide flags. Initializing a +headless program (with flags) from JavaScript looks like this: + +```javascript +var app = Elm.MyThing.worker({ user: 'Tom', token: 1234 }); +``` + +Whatever argument you provide to `worker` will get converted to an Elm value, +allowing you to configure your Elm program however you want from JavaScript! +-} +programWithFlags + : { init : flags -> (model, Cmd msg) + , update : msg -> model -> (model, Cmd msg) + , subscriptions : model -> Sub msg + } + -> Program flags model msg +programWithFlags = + Native.Platform.programWithFlags + + + +-- TASKS and PROCESSES + +{-| Head over to the documentation for the [`Task`](Task) module for more +information on this. It is only defined here because it is a platform +primitive. +-} +type Task err ok = Task + + +{-| Head over to the documentation for the [`Process`](Process) module for +information on this. It is only defined here because it is a platform +primitive. +-} +type ProcessId = ProcessId + + + +-- EFFECT MANAGER INTERNALS + + +{-| An effect manager has access to a “router” that routes messages between +the main app and your individual effect manager. +-} +type Router appMsg selfMsg = + Router + + +{-| Send the router a message for the main loop of your app. This message will +be handled by the overall `update` function, just like events from `Html`. +-} +sendToApp : Router msg a -> msg -> Task x () +sendToApp = + Native.Platform.sendToApp + + +{-| Send the router a message for your effect manager. This message will +be routed to the `onSelfMsg` function, where you can update the state of your +effect manager as necessary. + +As an example, the effect manager for web sockets +-} +sendToSelf : Router a msg -> msg -> Task x () +sendToSelf = + Native.Platform.sendToSelf + + +hack = + Native.Scheduler.succeed diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform/Cmd.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform/Cmd.elm new file mode 100644 index 0000000..a4ae4ed --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform/Cmd.elm @@ -0,0 +1,67 @@ +module Platform.Cmd exposing + ( Cmd + , map + , batch + , none + , (!) + ) + +{-| + +# Effects + +Elm has **managed effects**, meaning that things like HTTP requests or writing +to disk are all treated as *data* in Elm. When this data is given to the Elm +runtime system, it can do some “query optimization” before actually performing +the effect. Perhaps unexpectedly, this managed effects idea is the heart of why +Elm is so nice for testing, reuse, reproducibility, etc. + +There are two kinds of managed effects you will use in your programs: commands +and subscriptions. + +@docs Cmd, map, batch, none, (!) + +-} + +import Native.Platform + + +{-| A command is a way of telling Elm, “Hey, I want you to do this thing!” +So if you want to send an HTTP request, you would need to command Elm to do it. +Or if you wanted to ask for geolocation, you would need to command Elm to go +get it. + +Every `Cmd` specifies (1) which effects you need access to and (2) the type of +messages that will come back into your application. + +**Note:** Do not worry if this seems confusing at first! As with every Elm user +ever, commands will make more sense as you work through [the Elm Architecture +Tutorial](http://guide.elm-lang.org/architecture/index.html) and see how they +fit into a real application! +-} +type Cmd msg = Cmd + + +{-|-} +map : (a -> msg) -> Cmd a -> Cmd msg +map = + Native.Platform.map + + +{-|-} +batch : List (Cmd msg) -> Cmd msg +batch = + Native.Platform.batch + + +{-|-} +none : Cmd msg +none = + batch [] + + +{-|-} +(!) : model -> List (Cmd msg) -> (model, Cmd msg) +(!) model commands = + (model, batch commands) + diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform/Sub.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform/Sub.elm new file mode 100644 index 0000000..03f2f81 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Platform/Sub.elm @@ -0,0 +1,52 @@ +module Platform.Sub exposing + ( Sub + , map + , batch + , none + ) + +{-| + +@docs Sub, map, batch, none +-} + +import Native.Platform + + +{-| A subscription is a way of telling Elm, “Hey, let me know if anything +interesting happens over there!” So if you want to listen for messages on a web +socket, you would tell Elm to create a subscription. If you want to get clock +ticks, you would tell Elm to subscribe to that. The cool thing here is that +this means *Elm* manages all the details of subscriptions instead of *you*. +So if a web socket goes down, *you* do not need to manually reconnect with an +exponential backoff strategy, *Elm* does this all for you behind the scenes! + +Every `Sub` specifies (1) which effects you need access to and (2) the type of +messages that will come back into your application. + +**Note:** Do not worry if this seems confusing at first! As with every Elm user +ever, subscriptions will make more sense as you work through [the Elm Architecture +Tutorial](http://guide.elm-lang.org/architecture/index.html) and see how they fit +into a real application! +-} +type Sub msg = Sub + + +{-|-} +map : (a -> msg) -> Sub a -> Sub msg +map = + Native.Platform.map + + +{-|-} +batch : List (Sub msg) -> Sub msg +batch = + Native.Platform.batch + + +{-|-} +none : Sub msg +none = + batch [] + + diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Process.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Process.elm new file mode 100644 index 0000000..0ef59af --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Process.elm @@ -0,0 +1,106 @@ +module Process exposing + ( Id + , spawn + , sleep + , kill + ) + +{-| + +# Processes +@docs Id, spawn, sleep, kill + +## Future Plans + +Right now, this library is pretty sparse. For example, there is no public API +for processes to communicate with each other. This is a really important +ability, but it is also something that is extraordinarily easy to get wrong! + +I think the trend will be towards an Erlang style of concurrency, where every +process has an “event queue” that anyone can send messages to. I currently +think the API will be extended to be more like this: + + type Id exit msg + + spawn : Task exit a -> Task x (Id exit Never) + + kill : Id exit msg -> Task x () + + send : Id exit msg -> msg -> Task x () + +A process `Id` will have two type variables to make sure all communication is +valid. The `exit` type describes the messages that are produced if the process +fails because of user code. So if processes are linked and trapping errors, +they will need to handle this. The `msg` type just describes what kind of +messages this process can be sent by strangers. + +We shall see though! This is just a draft that does not cover nearly everything +it needs to, so the long-term vision for concurrency in Elm will be rolling out +slowly as I get more data and experience. + +I ask that people bullish on compiling to node.js keep this in mind. I think we +can do better than the hopelessly bad concurrency model of node.js, and I hope +the Elm community will be supportive of being more ambitious, even if it takes +longer. That’s kind of what Elm is all about. +-} + +import Basics exposing (Never) +import Native.Scheduler +import Platform +import Task exposing (Task) +import Time exposing (Time) + + +{-| A light-weight process that runs concurrently. You can use `spawn` to +get a bunch of different tasks running in different processes. The Elm runtime +will interleave their progress. So if a task is taking too long, we will pause +it at an `andThen` and switch over to other stuff. + +**Note:** We make a distinction between *concurrency* which means interleaving +different sequences and *parallelism* which means running different +sequences at the exact same time. For example, a +[time-sharing system](https://en.wikipedia.org/wiki/Time-sharing) is definitely +concurrent, but not necessarily parallel. So even though JS runs within a +single OS-level thread, Elm can still run things concurrently. +-} +type alias Id = + Platform.ProcessId + + +{-| Run a task in its own light-weight process. In the following example, +`task1` and `task2` will be interleaved. If `task1` makes a long HTTP request +or is just taking a long time, we can hop over to `task2` and do some work +there. + + spawn task1 + |> Task.andThen (\_ -> spawn task2) + +**Note:** This creates a relatively restricted kind of `Process` because it +cannot receive any messages. More flexibility for user-defined processes will +come in a later release! +-} +spawn : Task x a -> Task y Id +spawn = + Native.Scheduler.spawn + + +{-| Block progress on the current process for a given amount of time. The +JavaScript equivalent of this is [`setTimeout`][setTimeout] which lets you +delay work until later. + +[setTimeout]: https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout +-} +sleep : Time -> Task x () +sleep = + Native.Scheduler.sleep + + +{-| Sometimes you `spawn` a process, but later decide it would be a waste to +have it keep running and doing stuff. The `kill` function will force a process +to bail on whatever task it is running. So if there is an HTTP request in +flight, it will also abort the request. +-} +kill : Id -> Task x () +kill = + Native.Scheduler.kill + diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Random.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Random.elm new file mode 100644 index 0000000..d506433 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Random.elm @@ -0,0 +1,532 @@ +effect module Random where { command = MyCmd } exposing + ( Generator, Seed + , bool, int, float + , list, pair + , map, map2, map3, map4, map5 + , andThen + , minInt, maxInt + , generate + , step, initialSeed + ) + +{-| This library helps you generate pseudo-random values. + +This library is all about building [`generators`](#Generator) for whatever +type of values you need. There are a bunch of primitive generators like +[`bool`](#bool) and [`int`](#int) that you can build up into fancier +generators with functions like [`list`](#list) and [`map`](#map). + +It may be helpful to [read about JSON decoders][json] because they work very +similarly. + +[json]: https://evancz.gitbooks.io/an-introduction-to-elm/content/interop/json.html + +> *Note:* This is an implementation of the Portable Combined Generator of +L'Ecuyer for 32-bit computers. It is almost a direct translation from the +[System.Random](http://hackage.haskell.org/package/random-1.0.1.1/docs/System-Random.html) +module. It has a period of roughly 2.30584e18. + +# Generators +@docs Generator + +# Primitive Generators +@docs bool, int, float + +# Data Structure Generators +@docs pair, list + +# Custom Generators +@docs map, map2, map3, map4, map5, andThen + +# Generate Values +@docs generate + +# Generate Values Manually +@docs step, Seed, initialSeed + +# Constants +@docs maxInt, minInt + +-} + +import Basics exposing (..) +import List exposing ((::)) +import Platform +import Platform.Cmd exposing (Cmd) +import Task exposing (Task) +import Time +import Tuple + + + +-- PRIMITIVE GENERATORS + + +{-| Create a generator that produces boolean values. The following example +simulates a coin flip that may land heads or tails. + + type Flip = Heads | Tails + + coinFlip : Generator Flip + coinFlip = + map (\b -> if b then Heads else Tails) bool +-} +bool : Generator Bool +bool = + map ((==) 1) (int 0 1) + + +{-| Generate 32-bit integers in a given range. + + int 0 10 -- an integer between zero and ten + int -5 5 -- an integer between -5 and 5 + + int minInt maxInt -- an integer in the widest range feasible + +This function *can* produce values outside of the range [[`minInt`](#minInt), +[`maxInt`](#maxInt)] but sufficient randomness is not guaranteed. +-} +int : Int -> Int -> Generator Int +int a b = + Generator <| \(Seed seed) -> + let + (lo,hi) = + if a < b then (a,b) else (b,a) + + k = hi - lo + 1 + -- 2^31 - 87 + base = 2147483561 + n = iLogBase base k + + f n acc state = + case n of + 0 -> (acc, state) + _ -> + let + (x, nextState) = seed.next state + in + f (n - 1) (x + acc * base) nextState + + (v, nextState) = + f n 1 seed.state + in + ( lo + v % k + , Seed { seed | state = nextState } + ) + + +iLogBase : Int -> Int -> Int +iLogBase b i = + if i < b then + 1 + else + 1 + iLogBase b (i // b) + + +{-| The maximum value for randomly generated 32-bit ints: 2147483647 -} +maxInt : Int +maxInt = + 2147483647 + + +{-| The minimum value for randomly generated 32-bit ints: -2147483648 -} +minInt : Int +minInt = + -2147483648 + + +{-| Generate floats in a given range. The following example is a generator +that produces decimals between 0 and 1. + + probability : Generator Float + probability = + float 0 1 +-} +float : Float -> Float -> Generator Float +float a b = + Generator <| \seed -> + let + (lo, hi) = + if a < b then (a,b) else (b,a) + + (number, newSeed) = + step (int minInt maxInt) seed + + negativeOneToOne = + toFloat number / toFloat (maxInt - minInt) + + scaled = + (lo+hi)/2 + ((hi-lo) * negativeOneToOne) + in + (scaled, newSeed) + + + +-- DATA STRUCTURES + + +{-| Create a pair of random values. A common use of this might be to generate +a point in a certain 2D space. Imagine we have a collage that is 400 pixels +wide and 200 pixels tall. + + randomPoint : Generator (Int,Int) + randomPoint = + pair (int -200 200) (int -100 100) + +-} +pair : Generator a -> Generator b -> Generator (a,b) +pair genA genB = + map2 (,) genA genB + + +{-| Create a list of random values. + + floatList : Generator (List Float) + floatList = + list 10 (float 0 1) + + intList : Generator (List Int) + intList = + list 5 (int 0 100) + + intPairs : Generator (List (Int, Int)) + intPairs = + list 10 <| pair (int 0 100) (int 0 100) +-} +list : Int -> Generator a -> Generator (List a) +list n (Generator generate) = + Generator <| \seed -> + listHelp [] n generate seed + + +listHelp : List a -> Int -> (Seed -> (a,Seed)) -> Seed -> (List a, Seed) +listHelp list n generate seed = + if n < 1 then + (List.reverse list, seed) + + else + let + (value, newSeed) = + generate seed + in + listHelp (value :: list) (n-1) generate newSeed + + + +-- CUSTOM GENERATORS + + +{-| Transform the values produced by a generator. The following examples show +how to generate booleans and letters based on a basic integer generator. + + bool : Generator Bool + bool = + map ((==) 1) (int 0 1) + + lowercaseLetter : Generator Char + lowercaseLetter = + map (\n -> Char.fromCode (n + 97)) (int 0 25) + + uppercaseLetter : Generator Char + uppercaseLetter = + map (\n -> Char.fromCode (n + 65)) (int 0 25) + +-} +map : (a -> b) -> Generator a -> Generator b +map func (Generator genA) = + Generator <| \seed0 -> + let + (a, seed1) = genA seed0 + in + (func a, seed1) + + +{-| Combine two generators. + +This function is used to define things like [`pair`](#pair) where you want to +put two generators together. + + pair : Generator a -> Generator b -> Generator (a,b) + pair genA genB = + map2 (,) genA genB + +-} +map2 : (a -> b -> c) -> Generator a -> Generator b -> Generator c +map2 func (Generator genA) (Generator genB) = + Generator <| \seed0 -> + let + (a, seed1) = genA seed0 + (b, seed2) = genB seed1 + in + (func a b, seed2) + + +{-| Combine three generators. This could be used to produce random colors. + + import Color + + rgb : Generator Color.Color + rgb = + map3 Color.rgb (int 0 255) (int 0 255) (int 0 255) + + hsl : Generator Color.Color + hsl = + map3 Color.hsl (map degrees (int 0 360)) (float 0 1) (float 0 1) +-} +map3 : (a -> b -> c -> d) -> Generator a -> Generator b -> Generator c -> Generator d +map3 func (Generator genA) (Generator genB) (Generator genC) = + Generator <| \seed0 -> + let + (a, seed1) = genA seed0 + (b, seed2) = genB seed1 + (c, seed3) = genC seed2 + in + (func a b c, seed3) + + +{-| Combine four generators. +-} +map4 : (a -> b -> c -> d -> e) -> Generator a -> Generator b -> Generator c -> Generator d -> Generator e +map4 func (Generator genA) (Generator genB) (Generator genC) (Generator genD) = + Generator <| \seed0 -> + let + (a, seed1) = genA seed0 + (b, seed2) = genB seed1 + (c, seed3) = genC seed2 + (d, seed4) = genD seed3 + in + (func a b c d, seed4) + + +{-| Combine five generators. +-} +map5 : (a -> b -> c -> d -> e -> f) -> Generator a -> Generator b -> Generator c -> Generator d -> Generator e -> Generator f +map5 func (Generator genA) (Generator genB) (Generator genC) (Generator genD) (Generator genE) = + Generator <| \seed0 -> + let + (a, seed1) = genA seed0 + (b, seed2) = genB seed1 + (c, seed3) = genC seed2 + (d, seed4) = genD seed3 + (e, seed5) = genE seed4 + in + (func a b c d e, seed5) + + +{-| Chain random operations, threading through the seed. In the following +example, we will generate a random letter by putting together uppercase and +lowercase letters. + + letter : Generator Char + letter = + bool + |> andThen upperOrLower + + upperOrLower : Bool -> Generator Char + upperOrLower b = + if b then uppercaseLetter else lowercaseLetter + + -- bool : Generator Bool + -- uppercaseLetter : Generator Char + -- lowercaseLetter : Generator Char +-} +andThen : (a -> Generator b) -> Generator a -> Generator b +andThen callback (Generator generate) = + Generator <| \seed -> + let + (result, newSeed) = + generate seed + + (Generator genB) = + callback result + in + genB newSeed + + + +-- IMPLEMENTATION + + +{-| A `Generator` is like a recipe for generating certain random values. So a +`Generator Int` describes how to generate integers and a `Generator String` +describes how to generate strings. + +To actually *run* a generator and produce the random values, you need to use +functions like [`generate`](#generate) and [`initialSeed`](#initialSeed). +-} +type Generator a = + Generator (Seed -> (a, Seed)) + + +type State = State Int Int + + +{-| A `Seed` is the source of randomness in this whole system. Whenever +you want to use a generator, you need to pair it with a seed. +-} +type Seed = + Seed + { state : State + , next : State -> (Int, State) + , split : State -> (State, State) + , range : State -> (Int,Int) + } + + +{-| Generate a random value as specified by a given `Generator`. + +In the following example, we are trying to generate a number between 0 and 100 +with the `int 0 100` generator. Each time we call `step` we need to provide a +seed. This will produce a random number and a *new* seed to use if we want to +run other generators later. + +So here it is done right, where we get a new seed from each `step` call and +thread that through. + + seed0 = initialSeed 31415 + + -- step (int 0 100) seed0 ==> (42, seed1) + -- step (int 0 100) seed1 ==> (31, seed2) + -- step (int 0 100) seed2 ==> (99, seed3) + +Notice that we use different seeds on each line. This is important! If you use +the same seed, you get the same results. + + -- step (int 0 100) seed0 ==> (42, seed1) + -- step (int 0 100) seed0 ==> (42, seed1) + -- step (int 0 100) seed0 ==> (42, seed1) +-} +step : Generator a -> Seed -> (a, Seed) +step (Generator generator) seed = + generator seed + + +{-| Create a “seed” of randomness which makes it possible to +generate random values. If you use the same seed many times, it will result +in the same thing every time! A good way to get an unexpected seed is to use +the current time. +-} +initialSeed : Int -> Seed +initialSeed n = + Seed + { state = initState n + , next = next + , split = split + , range = range + } + + +{-| Produce the initial generator state. Distinct arguments should be likely +to produce distinct generator states. +-} +initState : Int -> State +initState seed = + let + s = max seed -seed + q = s // (magicNum6-1) + s1 = s % (magicNum6-1) + s2 = q % (magicNum7-1) + in + State (s1+1) (s2+1) + + +magicNum0 = 40014 +magicNum1 = 53668 +magicNum2 = 12211 +magicNum3 = 52774 +magicNum4 = 40692 +magicNum5 = 3791 +magicNum6 = 2147483563 +magicNum7 = 2147483399 +magicNum8 = 2147483562 + + +next : State -> (Int, State) +next (State state1 state2) = + -- Div always rounds down and so random numbers are biased + -- ideally we would use division that rounds towards zero so + -- that in the negative case it rounds up and in the positive case + -- it rounds down. Thus half the time it rounds up and half the time it + -- rounds down + let + k1 = state1 // magicNum1 + rawState1 = magicNum0 * (state1 - k1 * magicNum1) - k1 * magicNum2 + newState1 = if rawState1 < 0 then rawState1 + magicNum6 else rawState1 + k2 = state2 // magicNum3 + rawState2 = magicNum4 * (state2 - k2 * magicNum3) - k2 * magicNum5 + newState2 = if rawState2 < 0 then rawState2 + magicNum7 else rawState2 + z = newState1 - newState2 + newZ = if z < 1 then z + magicNum8 else z + in + (newZ, State newState1 newState2) + + +split : State -> (State, State) +split (State s1 s2 as std) = + let + new_s1 = + if s1 == magicNum6-1 then 1 else s1 + 1 + + new_s2 = + if s2 == 1 then magicNum7-1 else s2 - 1 + + (State t1 t2) = + Tuple.second (next std) + in + (State new_s1 t2, State t1 new_s2) + + +range : State -> (Int,Int) +range _ = + (0, magicNum8) + + + +-- MANAGER + + +{-| Create a command that will generate random values. + +Read more about how to use this in your programs in [The Elm Architecture +tutorial][arch] which has a section specifically [about random values][rand]. + +[arch]: https://evancz.gitbooks.io/an-introduction-to-elm/content/architecture/index.html +[rand]: https://evancz.gitbooks.io/an-introduction-to-elm/content/architecture/effects/random.html +-} +generate : (a -> msg) -> Generator a -> Cmd msg +generate tagger generator = + command (Generate (map tagger generator)) + + +type MyCmd msg = Generate (Generator msg) + + +cmdMap : (a -> b) -> MyCmd a -> MyCmd b +cmdMap func (Generate generator) = + Generate (map func generator) + + +init : Task Never Seed +init = + Time.now + |> Task.andThen (\t -> Task.succeed (initialSeed (round t))) + + +onEffects : Platform.Router msg Never -> List (MyCmd msg) -> Seed -> Task Never Seed +onEffects router commands seed = + case commands of + [] -> + Task.succeed seed + + Generate generator :: rest -> + let + (value, newSeed) = + step generator seed + in + Platform.sendToApp router value + |> Task.andThen (\_ -> onEffects router rest newSeed) + + +onSelfMsg : Platform.Router msg Never -> Never -> Seed -> Task Never Seed +onSelfMsg _ _ seed = + Task.succeed seed diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Regex.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Regex.elm new file mode 100644 index 0000000..2d58ecf --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Regex.elm @@ -0,0 +1,148 @@ +module Regex exposing + ( Regex + , regex, escape, caseInsensitive + , HowMany(..), Match + , contains, find, replace, split + ) + +{-| A library for working with regular expressions. It uses [the +same kind of regular expressions accepted by JavaScript](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions). + +# Create +@docs Regex, regex, escape, caseInsensitive + +# Helpful Data Structures + +These data structures are needed to help define functions like [`find`](#find) +and [`replace`](#replace). + +@docs HowMany, Match + +# Use +@docs contains, find, replace, split + +-} + +import Maybe exposing (Maybe) +import Native.Regex + + +{-| A regular expression, describing a certain set of strings. +-} +type Regex = Regex + + +{-| Escape strings to be regular expressions, making all special characters +safe. So `regex (escape "^a+")` will match exactly `"^a+"` instead of a series +of `a`’s that start at the beginning of the line. +-} +escape : String -> String +escape = + Native.Regex.escape + + +{-| Create a Regex that matches patterns [as specified in JavaScript](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Writing_a_Regular_Expression_Pattern). + +Be careful to escape backslashes properly! For example, `"\w"` is escaping the +letter `w` which is probably not what you want. You probably want `"\\w"` +instead, which escapes the backslash. +-} +regex : String -> Regex +regex = + Native.Regex.regex + + + +{-| Make a regex case insensitive -} +caseInsensitive : Regex -> Regex +caseInsensitive = + Native.Regex.caseInsensitive + + +{-| Check to see if a Regex is contained in a string. + + contains (regex "123") "12345" == True + contains (regex "b+") "aabbcc" == True + + contains (regex "789") "12345" == False + contains (regex "z+") "aabbcc" == False +-} +contains : Regex -> String -> Bool +contains = + Native.Regex.contains + + +{-| A `Match` represents all of the details about a particular match in a string. +Here are details on each field: + + * `match` — the full string of the match. + * `submatches` — a regex might have [subpatterns, surrounded by + parentheses](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Parenthesized_Substring_Matches). + If there are N subpatterns, there will be N elements in the `submatches` list. + Each submatch in this list is a `Maybe` because not all subpatterns may trigger. + For example, `(regex "(a+)|(b+)")` will either match many `a`’s or + many `b`’s, but never both. + * `index` — the index of the match in the original string. + * `number` — if you find many matches, you can think of each one + as being labeled with a `number` starting at one. So the first time you + find a match, that is match `number` one. Second time is match `number` two. + This is useful when paired with `replace All` if replacement is dependent on how + many times a pattern has appeared before. +-} +type alias Match = + { match : String + , submatches : List (Maybe String) + , index : Int + , number : Int + } + + +{-| `HowMany` is used to specify how many matches you want to make. So +`replace All` would replace every match, but `replace (AtMost 2)` would +replace at most two matches (i.e. zero, one, two, but never three or more). +-} +type HowMany = All | AtMost Int + + +{-| Find matches in a string: + + findTwoCommas = find (AtMost 2) (regex ",") + + -- map .index (findTwoCommas "a,b,c,d,e") == [1,3] + -- map .index (findTwoCommas "a b c d e") == [] + + places = find All (regex "[oi]n a (\\w+)") "I am on a boat in a lake." + + -- map .match places == ["on a boat", "in a lake"] + -- map .submatches places == [ [Just "boat"], [Just "lake"] ] +-} +find : HowMany -> Regex -> String -> List Match +find = + Native.Regex.find + + +{-| Replace matches. The function from `Match` to `String` lets +you use the details of a specific match when making replacements. + + devowel = replace All (regex "[aeiou]") (\_ -> "") + + -- devowel "The quick brown fox" == "Th qck brwn fx" + + reverseWords = replace All (regex "\\w+") (\{match} -> String.reverse match) + + -- reverseWords "deliver mined parts" == "reviled denim strap" +-} +replace : HowMany -> Regex -> (Match -> String) -> String -> String +replace = + Native.Regex.replace + + +{-| Split a string, using the regex as the separator. + + split (AtMost 1) (regex ",") "tom,99,90,85" == ["tom","99,90,85"] + + split All (regex ",") "a,b,c,d" == ["a","b","c","d"] +-} +split : HowMany -> Regex -> String -> List String +split = + Native.Regex.split diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Result.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Result.elm new file mode 100644 index 0000000..61c678c --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Result.elm @@ -0,0 +1,210 @@ +module Result exposing + ( Result(..) + , withDefault + , map, map2, map3, map4, map5 + , andThen + , toMaybe, fromMaybe, mapError + ) + +{-| A `Result` is the result of a computation that may fail. This is a great +way to manage errors in Elm. + +# Type and Constructors +@docs Result + +# Mapping +@docs map, map2, map3, map4, map5 + +# Chaining +@docs andThen + +# Handling Errors +@docs withDefault, toMaybe, fromMaybe, mapError +-} + +import Maybe exposing ( Maybe(Just, Nothing) ) + + +{-| A `Result` is either `Ok` meaning the computation succeeded, or it is an +`Err` meaning that there was some failure. +-} +type Result error value + = Ok value + | Err error + + +{-| If the result is `Ok` return the value, but if the result is an `Err` then +return a given default value. The following examples try to parse integers. + + Result.withDefault 0 (String.toInt "123") == 123 + Result.withDefault 0 (String.toInt "abc") == 0 +-} +withDefault : a -> Result x a -> a +withDefault def result = + case result of + Ok a -> + a + + Err _ -> + def + + +{-| Apply a function to a result. If the result is `Ok`, it will be converted. +If the result is an `Err`, the same error value will propagate through. + + map sqrt (Ok 4.0) == Ok 2.0 + map sqrt (Err "bad input") == Err "bad input" +-} +map : (a -> value) -> Result x a -> Result x value +map func ra = + case ra of + Ok a -> Ok (func a) + Err e -> Err e + + +{-| Apply a function to two results, if both results are `Ok`. If not, +the first argument which is an `Err` will propagate through. + + map2 (+) (String.toInt "1") (String.toInt "2") == Ok 3 + map2 (+) (String.toInt "1") (String.toInt "y") == Err "could not convert string 'y' to an Int" + map2 (+) (String.toInt "x") (String.toInt "y") == Err "could not convert string 'x' to an Int" +-} +map2 : (a -> b -> value) -> Result x a -> Result x b -> Result x value +map2 func ra rb = + case (ra,rb) of + (Ok a, Ok b) -> Ok (func a b) + (Err x, _) -> Err x + (_, Err x) -> Err x + + +{-|-} +map3 : (a -> b -> c -> value) -> Result x a -> Result x b -> Result x c -> Result x value +map3 func ra rb rc = + case (ra,rb,rc) of + (Ok a, Ok b, Ok c) -> Ok (func a b c) + (Err x, _, _) -> Err x + (_, Err x, _) -> Err x + (_, _, Err x) -> Err x + + +{-|-} +map4 : (a -> b -> c -> d -> value) -> Result x a -> Result x b -> Result x c -> Result x d -> Result x value +map4 func ra rb rc rd = + case (ra,rb,rc,rd) of + (Ok a, Ok b, Ok c, Ok d) -> Ok (func a b c d) + (Err x, _, _, _) -> Err x + (_, Err x, _, _) -> Err x + (_, _, Err x, _) -> Err x + (_, _, _, Err x) -> Err x + + +{-|-} +map5 : (a -> b -> c -> d -> e -> value) -> Result x a -> Result x b -> Result x c -> Result x d -> Result x e -> Result x value +map5 func ra rb rc rd re = + case (ra,rb,rc,rd,re) of + (Ok a, Ok b, Ok c, Ok d, Ok e) -> Ok (func a b c d e) + (Err x, _, _, _, _) -> Err x + (_, Err x, _, _, _) -> Err x + (_, _, Err x, _, _) -> Err x + (_, _, _, Err x, _) -> Err x + (_, _, _, _, Err x) -> Err x + + +{-| Chain together a sequence of computations that may fail. It is helpful +to see its definition: + + andThen : (a -> Result e b) -> Result e a -> Result e b + andThen callback result = + case result of + Ok value -> callback value + Err msg -> Err msg + +This means we only continue with the callback if things are going well. For +example, say you need to use (`toInt : String -> Result String Int`) to parse +a month and make sure it is between 1 and 12: + + toValidMonth : Int -> Result String Int + toValidMonth month = + if month >= 1 && month <= 12 + then Ok month + else Err "months must be between 1 and 12" + + toMonth : String -> Result String Int + toMonth rawString = + toInt rawString + |> andThen toValidMonth + + -- toMonth "4" == Ok 4 + -- toMonth "9" == Ok 9 + -- toMonth "a" == Err "cannot parse to an Int" + -- toMonth "0" == Err "months must be between 1 and 12" + +This allows us to come out of a chain of operations with quite a specific error +message. It is often best to create a custom type that explicitly represents +the exact ways your computation may fail. This way it is easy to handle in your +code. +-} +andThen : (a -> Result x b) -> Result x a -> Result x b +andThen callback result = + case result of + Ok value -> + callback value + + Err msg -> + Err msg + + +{-| Transform an `Err` value. For example, say the errors we get have too much +information: + + parseInt : String -> Result ParseError Int + + type alias ParseError = + { message : String + , code : Int + , position : (Int,Int) + } + + mapError .message (parseInt "123") == Ok 123 + mapError .message (parseInt "abc") == Err "char 'a' is not a number" +-} +mapError : (x -> y) -> Result x a -> Result y a +mapError f result = + case result of + Ok v -> + Ok v + + Err e -> + Err (f e) + + +{-| Convert to a simpler `Maybe` if the actual error message is not needed or +you need to interact with some code that primarily uses maybes. + + parseInt : String -> Result ParseError Int + + maybeParseInt : String -> Maybe Int + maybeParseInt string = + toMaybe (parseInt string) +-} +toMaybe : Result x a -> Maybe a +toMaybe result = + case result of + Ok v -> Just v + Err _ -> Nothing + + +{-| Convert from a simple `Maybe` to interact with some code that primarily +uses `Results`. + + parseInt : String -> Maybe Int + + resultParseInt : String -> Result String Int + resultParseInt string = + fromMaybe ("error parsing string: " ++ toString string) (parseInt string) +-} +fromMaybe : x -> Maybe a -> Result x a +fromMaybe err maybe = + case maybe of + Just v -> Ok v + Nothing -> Err err diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Set.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Set.elm new file mode 100644 index 0000000..9b1914a --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Set.elm @@ -0,0 +1,168 @@ +module Set exposing + ( Set + , empty, singleton, insert, remove + , isEmpty, member, size + , foldl, foldr, map + , filter, partition + , union, intersect, diff + , toList, fromList + ) + +{-| A set of unique values. The values can be any comparable type. This +includes `Int`, `Float`, `Time`, `Char`, `String`, and tuples or lists +of comparable types. + +Insert, remove, and query operations all take *O(log n)* time. + +# Sets +@docs Set + +# Build +@docs empty, singleton, insert, remove + +# Query +@docs isEmpty, member, size + +# Combine +@docs union, intersect, diff + +# Lists +@docs toList, fromList + +# Transform +@docs map, foldl, foldr, filter, partition + +-} + +import Basics exposing ((<|)) +import Dict as Dict +import List as List + + +{-| Represents a set of unique values. So `(Set Int)` is a set of integers and +`(Set String)` is a set of strings. +-} +type Set t = + Set_elm_builtin (Dict.Dict t ()) + + +{-| Create an empty set. +-} +empty : Set a +empty = + Set_elm_builtin Dict.empty + + +{-| Create a set with one value. +-} +singleton : comparable -> Set comparable +singleton k = + Set_elm_builtin <| Dict.singleton k () + + +{-| Insert a value into a set. +-} +insert : comparable -> Set comparable -> Set comparable +insert k (Set_elm_builtin d) = + Set_elm_builtin <| Dict.insert k () d + + +{-| Remove a value from a set. If the value is not found, no changes are made. +-} +remove : comparable -> Set comparable -> Set comparable +remove k (Set_elm_builtin d) = + Set_elm_builtin <| Dict.remove k d + + +{-| Determine if a set is empty. +-} +isEmpty : Set a -> Bool +isEmpty (Set_elm_builtin d) = + Dict.isEmpty d + + +{-| Determine if a value is in a set. +-} +member : comparable -> Set comparable -> Bool +member k (Set_elm_builtin d) = + Dict.member k d + + +{-| Determine the number of elements in a set. +-} +size : Set a -> Int +size (Set_elm_builtin d) = + Dict.size d + + +{-| Get the union of two sets. Keep all values. +-} +union : Set comparable -> Set comparable -> Set comparable +union (Set_elm_builtin d1) (Set_elm_builtin d2) = + Set_elm_builtin <| Dict.union d1 d2 + + +{-| Get the intersection of two sets. Keeps values that appear in both sets. +-} +intersect : Set comparable -> Set comparable -> Set comparable +intersect (Set_elm_builtin d1) (Set_elm_builtin d2) = + Set_elm_builtin <| Dict.intersect d1 d2 + + +{-| Get the difference between the first set and the second. Keeps values +that do not appear in the second set. +-} +diff : Set comparable -> Set comparable -> Set comparable +diff (Set_elm_builtin d1) (Set_elm_builtin d2) = + Set_elm_builtin <| Dict.diff d1 d2 + + +{-| Convert a set into a list, sorted from lowest to highest. +-} +toList : Set comparable -> List comparable +toList (Set_elm_builtin d) = + Dict.keys d + + +{-| Convert a list into a set, removing any duplicates. +-} +fromList : List comparable -> Set comparable +fromList xs = List.foldl insert empty xs + + +{-| Fold over the values in a set, in order from lowest to highest. +-} +foldl : (comparable -> b -> b) -> b -> Set comparable -> b +foldl f b (Set_elm_builtin d) = + Dict.foldl (\k _ b -> f k b) b d + + +{-| Fold over the values in a set, in order from highest to lowest. +-} +foldr : (comparable -> b -> b) -> b -> Set comparable -> b +foldr f b (Set_elm_builtin d) = + Dict.foldr (\k _ b -> f k b) b d + + +{-| Map a function onto a set, creating a new set with no duplicates. +-} +map : (comparable -> comparable2) -> Set comparable -> Set comparable2 +map f s = fromList (List.map f (toList s)) + + +{-| Create a new set consisting only of elements which satisfy a predicate. +-} +filter : (comparable -> Bool) -> Set comparable -> Set comparable +filter p (Set_elm_builtin d) = + Set_elm_builtin <| Dict.filter (\k _ -> p k) d + + +{-| Create two new sets; the first consisting of elements which satisfy a +predicate, the second consisting of elements which do not. +-} +partition : (comparable -> Bool) -> Set comparable -> (Set comparable, Set comparable) +partition p (Set_elm_builtin d) = + let + (p1, p2) = Dict.partition (\k _ -> p k) d + in + (Set_elm_builtin p1, Set_elm_builtin p2) diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/String.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/String.elm new file mode 100644 index 0000000..a648e8d --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/String.elm @@ -0,0 +1,464 @@ +module String exposing + ( isEmpty, length, reverse, repeat + , cons, uncons, fromChar, append, concat, split, join, words, lines + , slice, left, right, dropLeft, dropRight + , contains, startsWith, endsWith, indexes, indices + , toInt, toFloat, toList, fromList + , toUpper, toLower, pad, padLeft, padRight, trim, trimLeft, trimRight + , map, filter, foldl, foldr, any, all + ) + +{-| A built-in representation for efficient string manipulation. String literals +are enclosed in `"double quotes"`. Strings are *not* lists of characters. + +# Basics +@docs isEmpty, length, reverse, repeat + +# Building and Splitting +@docs cons, uncons, fromChar, append, concat, split, join, words, lines + +# Get Substrings +@docs slice, left, right, dropLeft, dropRight + +# Check for Substrings +@docs contains, startsWith, endsWith, indexes, indices + +# Conversions +@docs toInt, toFloat, toList, fromList + +# Formatting +Cosmetic operations such as padding with extra characters or trimming whitespace. + +@docs toUpper, toLower, + pad, padLeft, padRight, + trim, trimLeft, trimRight + +# Higher-Order Functions +@docs map, filter, foldl, foldr, any, all +-} + +import Native.String +import Char +import Maybe exposing (Maybe) +import Result exposing (Result) + + +{-| Determine if a string is empty. + + isEmpty "" == True + isEmpty "the world" == False +-} +isEmpty : String -> Bool +isEmpty = + Native.String.isEmpty + + +{-| Add a character to the beginning of a string. + + cons 'T' "he truth is out there" == "The truth is out there" +-} +cons : Char -> String -> String +cons = + Native.String.cons + + +{-| Create a string from a given character. + + fromChar 'a' == "a" +-} +fromChar : Char -> String +fromChar char = + cons char "" + + +{-| Split a non-empty string into its head and tail. This lets you +pattern match on strings exactly as you would with lists. + + uncons "abc" == Just ('a',"bc") + uncons "" == Nothing +-} +uncons : String -> Maybe (Char, String) +uncons = + Native.String.uncons + + +{-| Append two strings. You can also use [the `(++)` operator](Basics#++) +to do this. + + append "butter" "fly" == "butterfly" +-} +append : String -> String -> String +append = + Native.String.append + + +{-| Concatenate many strings into one. + + concat ["never","the","less"] == "nevertheless" +-} +concat : List String -> String +concat = + Native.String.concat + + +{-| Get the length of a string. + + length "innumerable" == 11 + length "" == 0 + +-} +length : String -> Int +length = + Native.String.length + + +{-| Transform every character in a string + + map (\c -> if c == '/' then '.' else c) "a/b/c" == "a.b.c" +-} +map : (Char -> Char) -> String -> String +map = + Native.String.map + + +{-| Keep only the characters that satisfy the predicate. + + filter isDigit "R2-D2" == "22" +-} +filter : (Char -> Bool) -> String -> String +filter = + Native.String.filter + + +{-| Reverse a string. + + reverse "stressed" == "desserts" +-} +reverse : String -> String +reverse = + Native.String.reverse + + +{-| Reduce a string from the left. + + foldl cons "" "time" == "emit" +-} +foldl : (Char -> b -> b) -> b -> String -> b +foldl = + Native.String.foldl + + +{-| Reduce a string from the right. + + foldr cons "" "time" == "time" +-} +foldr : (Char -> b -> b) -> b -> String -> b +foldr = + Native.String.foldr + + +{-| Split a string using a given separator. + + split "," "cat,dog,cow" == ["cat","dog","cow"] + split "/" "home/evan/Desktop/" == ["home","evan","Desktop", ""] + +Use [`Regex.split`](Regex#split) if you need something more flexible. +-} +split : String -> String -> List String +split = + Native.String.split + + +{-| Put many strings together with a given separator. + + join "a" ["H","w","ii","n"] == "Hawaiian" + join " " ["cat","dog","cow"] == "cat dog cow" + join "/" ["home","evan","Desktop"] == "home/evan/Desktop" +-} +join : String -> List String -> String +join = + Native.String.join + + +{-| Repeat a string *n* times. + + repeat 3 "ha" == "hahaha" +-} +repeat : Int -> String -> String +repeat = + Native.String.repeat + + +{-| Take a substring given a start and end index. Negative indexes +are taken starting from the *end* of the list. + + slice 7 9 "snakes on a plane!" == "on" + slice 0 6 "snakes on a plane!" == "snakes" + slice 0 -7 "snakes on a plane!" == "snakes on a" + slice -6 -1 "snakes on a plane!" == "plane" +-} +slice : Int -> Int -> String -> String +slice = + Native.String.slice + + +{-| Take *n* characters from the left side of a string. + + left 2 "Mulder" == "Mu" +-} +left : Int -> String -> String +left = + Native.String.left + + +{-| Take *n* characters from the right side of a string. + + right 2 "Scully" == "ly" +-} +right : Int -> String -> String +right = + Native.String.right + + +{-| Drop *n* characters from the left side of a string. + + dropLeft 2 "The Lone Gunmen" == "e Lone Gunmen" +-} +dropLeft : Int -> String -> String +dropLeft = + Native.String.dropLeft + + +{-| Drop *n* characters from the right side of a string. + + dropRight 2 "Cigarette Smoking Man" == "Cigarette Smoking M" +-} +dropRight : Int -> String -> String +dropRight = + Native.String.dropRight + + +{-| Pad a string on both sides until it has a given length. + + pad 5 ' ' "1" == " 1 " + pad 5 ' ' "11" == " 11 " + pad 5 ' ' "121" == " 121 " +-} +pad : Int -> Char -> String -> String +pad = + Native.String.pad + + +{-| Pad a string on the left until it has a given length. + + padLeft 5 '.' "1" == "....1" + padLeft 5 '.' "11" == "...11" + padLeft 5 '.' "121" == "..121" +-} +padLeft : Int -> Char -> String -> String +padLeft = + Native.String.padLeft + + +{-| Pad a string on the right until it has a given length. + + padRight 5 '.' "1" == "1...." + padRight 5 '.' "11" == "11..." + padRight 5 '.' "121" == "121.." +-} +padRight : Int -> Char -> String -> String +padRight = + Native.String.padRight + + +{-| Get rid of whitespace on both sides of a string. + + trim " hats \n" == "hats" +-} +trim : String -> String +trim = + Native.String.trim + + +{-| Get rid of whitespace on the left of a string. + + trimLeft " hats \n" == "hats \n" +-} +trimLeft : String -> String +trimLeft = + Native.String.trimLeft + + +{-| Get rid of whitespace on the right of a string. + + trimRight " hats \n" == " hats" +-} +trimRight : String -> String +trimRight = + Native.String.trimRight + + +{-| Break a string into words, splitting on chunks of whitespace. + + words "How are \t you? \n Good?" == ["How","are","you?","Good?"] +-} +words : String -> List String +words = + Native.String.words + + +{-| Break a string into lines, splitting on newlines. + + lines "How are you?\nGood?" == ["How are you?", "Good?"] +-} +lines : String -> List String +lines = + Native.String.lines + + +{-| Convert a string to all upper case. Useful for case-insensitive comparisons +and VIRTUAL YELLING. + + toUpper "skinner" == "SKINNER" +-} +toUpper : String -> String +toUpper = + Native.String.toUpper + + +{-| Convert a string to all lower case. Useful for case-insensitive comparisons. + + toLower "X-FILES" == "x-files" +-} +toLower : String -> String +toLower = + Native.String.toLower + + +{-| Determine whether *any* characters satisfy a predicate. + + any isDigit "90210" == True + any isDigit "R2-D2" == True + any isDigit "heart" == False +-} +any : (Char -> Bool) -> String -> Bool +any = + Native.String.any + + +{-| Determine whether *all* characters satisfy a predicate. + + all isDigit "90210" == True + all isDigit "R2-D2" == False + all isDigit "heart" == False +-} +all : (Char -> Bool) -> String -> Bool +all = + Native.String.all + + +{-| See if the second string contains the first one. + + contains "the" "theory" == True + contains "hat" "theory" == False + contains "THE" "theory" == False + +Use [`Regex.contains`](Regex#contains) if you need something more flexible. +-} +contains : String -> String -> Bool +contains = + Native.String.contains + + +{-| See if the second string starts with the first one. + + startsWith "the" "theory" == True + startsWith "ory" "theory" == False +-} +startsWith : String -> String -> Bool +startsWith = + Native.String.startsWith + + +{-| See if the second string ends with the first one. + + endsWith "the" "theory" == False + endsWith "ory" "theory" == True +-} +endsWith : String -> String -> Bool +endsWith = + Native.String.endsWith + + +{-| Get all of the indexes for a substring in another string. + + indexes "i" "Mississippi" == [1,4,7,10] + indexes "ss" "Mississippi" == [2,5] + indexes "needle" "haystack" == [] +-} +indexes : String -> String -> List Int +indexes = + Native.String.indexes + + +{-| Alias for `indexes`. -} +indices : String -> String -> List Int +indices = + Native.String.indexes + + +{-| Try to convert a string into an int, failing on improperly formatted strings. + + String.toInt "123" == Ok 123 + String.toInt "-42" == Ok -42 + String.toInt "3.1" == Err "could not convert string '3.1' to an Int" + String.toInt "31a" == Err "could not convert string '31a' to an Int" + +If you are extracting a number from some raw user input, you will typically +want to use [`Result.withDefault`](Result#withDefault) to handle bad data: + + Result.withDefault 0 (String.toInt "42") == 42 + Result.withDefault 0 (String.toInt "ab") == 0 +-} +toInt : String -> Result String Int +toInt = + Native.String.toInt + + +{-| Try to convert a string into a float, failing on improperly formatted strings. + + String.toFloat "123" == Ok 123.0 + String.toFloat "-42" == Ok -42.0 + String.toFloat "3.1" == Ok 3.1 + String.toFloat "31a" == Err "could not convert string '31a' to a Float" + +If you are extracting a number from some raw user input, you will typically +want to use [`Result.withDefault`](Result#withDefault) to handle bad data: + + Result.withDefault 0 (String.toFloat "42.5") == 42.5 + Result.withDefault 0 (String.toFloat "cats") == 0 +-} +toFloat : String -> Result String Float +toFloat = + Native.String.toFloat + + +{-| Convert a string to a list of characters. + + toList "abc" == ['a','b','c'] +-} +toList : String -> List Char +toList = + Native.String.toList + + +{-| Convert a list of characters into a String. Can be useful if you +want to create a string primarily by consing, perhaps for decoding +something. + + fromList ['a','b','c'] == "abc" +-} +fromList : List Char -> String +fromList = + Native.String.fromList + diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Task.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Task.elm new file mode 100644 index 0000000..94fde9e --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Task.elm @@ -0,0 +1,277 @@ +effect module Task where { command = MyCmd } exposing + ( Task + , succeed, fail + , map, map2, map3, map4, map5 + , sequence + , andThen + , onError, mapError + , perform, attempt + ) + +{-| Tasks make it easy to describe asynchronous operations that may fail, like +HTTP requests or writing to a database. For more information, see the [Elm +documentation on Tasks](http://guide.elm-lang.org/error_handling/task.html). + +# Basics +@docs Task, succeed, fail + +# Mapping +@docs map, map2, map3, map4, map5 + +# Chaining +@docs andThen, sequence + +# Errors +@docs onError, mapError + +# Commands +@docs perform, attempt + +-} + +import Basics exposing (Never, (|>), (<<)) +import List exposing ((::)) +import Maybe exposing (Maybe(Just,Nothing)) +import Native.Scheduler +import Platform +import Platform.Cmd exposing (Cmd) +import Result exposing (Result(Ok,Err)) + + + +{-| Represents asynchronous effects that may fail. It is useful for stuff like +HTTP. + +For example, maybe we have a task with the type (`Task String User`). This means +that when we perform the task, it will either fail with a `String` message or +succeed with a `User`. So this could represent a task that is asking a server +for a certain user. +-} +type alias Task err ok = + Platform.Task err ok + + + +-- BASICS + + +{-| A task that succeeds immediately when run. + + succeed 42 -- results in 42 +-} +succeed : a -> Task x a +succeed = + Native.Scheduler.succeed + + +{-| A task that fails immediately when run. + + fail "file not found" : Task String a +-} +fail : x -> Task x a +fail = + Native.Scheduler.fail + + + +-- MAPPING + + +{-| Transform a task. + + map sqrt (succeed 9) -- succeed 3 +-} +map : (a -> b) -> Task x a -> Task x b +map func taskA = + taskA + |> andThen (\a -> succeed (func a)) + + +{-| Put the results of two tasks together. If either task fails, the whole +thing fails. It also runs in order so the first task will be completely +finished before the second task starts. + + map2 (+) (succeed 9) (succeed 3) -- succeed 12 +-} +map2 : (a -> b -> result) -> Task x a -> Task x b -> Task x result +map2 func taskA taskB = + taskA + |> andThen (\a -> taskB + |> andThen (\b -> succeed (func a b))) + + +{-|-} +map3 : (a -> b -> c -> result) -> Task x a -> Task x b -> Task x c -> Task x result +map3 func taskA taskB taskC = + taskA + |> andThen (\a -> taskB + |> andThen (\b -> taskC + |> andThen (\c -> succeed (func a b c)))) + + +{-|-} +map4 : (a -> b -> c -> d -> result) -> Task x a -> Task x b -> Task x c -> Task x d -> Task x result +map4 func taskA taskB taskC taskD = + taskA + |> andThen (\a -> taskB + |> andThen (\b -> taskC + |> andThen (\c -> taskD + |> andThen (\d -> succeed (func a b c d))))) + + +{-|-} +map5 : (a -> b -> c -> d -> e -> result) -> Task x a -> Task x b -> Task x c -> Task x d -> Task x e -> Task x result +map5 func taskA taskB taskC taskD taskE = + taskA + |> andThen (\a -> taskB + |> andThen (\b -> taskC + |> andThen (\c -> taskD + |> andThen (\d -> taskE + |> andThen (\e -> succeed (func a b c d e)))))) + + +{-| Start with a list of tasks, and turn them into a single task that returns a +list. The tasks will be run in order one-by-one and if any task fails the whole +sequence fails. + + sequence [ succeed 1, succeed 2 ] -- succeed [ 1, 2 ] + +This can be useful if you need to make a bunch of HTTP requests one-by-one. +-} +sequence : List (Task x a) -> Task x (List a) +sequence tasks = + case tasks of + [] -> + succeed [] + + task :: remainingTasks -> + map2 (::) task (sequence remainingTasks) + + + +-- CHAINING + + +{-| Chain together a task and a callback. The first task will run, and if it is +successful, you give the result to the callback resulting in another task. This +task then gets run. + + succeed 2 + |> andThen (\n -> succeed (n + 2)) + -- succeed 4 + +This is useful for chaining tasks together. Maybe you need to get a user from +your servers *and then* lookup their picture once you know their name. +-} +andThen : (a -> Task x b) -> Task x a -> Task x b +andThen = + Native.Scheduler.andThen + + +-- ERRORS + +{-| Recover from a failure in a task. If the given task fails, we use the +callback to recover. + + fail "file not found" + |> onError (\msg -> succeed 42) + -- succeed 42 + + succeed 9 + |> onError (\msg -> succeed 42) + -- succeed 9 +-} +onError : (x -> Task y a) -> Task x a -> Task y a +onError = + Native.Scheduler.onError + + +{-| Transform the error value. This can be useful if you need a bunch of error +types to match up. + + type Error = Http Http.Error | WebGL WebGL.Error + + getResources : Task Error Resource + getResources = + sequence [ mapError Http serverTask, mapError WebGL textureTask ] +-} +mapError : (x -> y) -> Task x a -> Task y a +mapError convert task = + task + |> onError (fail << convert) + + + +-- COMMANDS + + +type MyCmd msg = + Perform (Task Never msg) + + +{-| The only way to *do* things in Elm is to give commands to the Elm runtime. +So we describe some complex behavior with a `Task` and then command the runtime +to `perform` that task. For example, getting the current time looks like this: + + import Task + import Time exposing (Time) + + type Msg = Click | NewTime Time + + update : Msg -> Model -> ( Model, Cmd Msg ) + update msg model = + case msg of + Click -> + ( model, Task.perform NewTime Time.now ) + + NewTime time -> + ... +-} +perform : (a -> msg) -> Task Never a -> Cmd msg +perform toMessage task = + command (Perform (map toMessage task)) + + +{-| Command the Elm runtime to attempt a task that might fail! +-} +attempt : (Result x a -> msg) -> Task x a -> Cmd msg +attempt resultToMessage task = + command (Perform ( + task + |> andThen (succeed << resultToMessage << Ok) + |> onError (succeed << resultToMessage << Err) + )) + + +cmdMap : (a -> b) -> MyCmd a -> MyCmd b +cmdMap tagger (Perform task) = + Perform (map tagger task) + + + +-- MANAGER + + +init : Task Never () +init = + succeed () + + +onEffects : Platform.Router msg Never -> List (MyCmd msg) -> () -> Task Never () +onEffects router commands state = + map + (\_ -> ()) + (sequence (List.map (spawnCmd router) commands)) + + +onSelfMsg : Platform.Router msg Never -> Never -> () -> Task Never () +onSelfMsg _ _ _ = + succeed () + + +spawnCmd : Platform.Router msg Never -> MyCmd msg -> Task x () +spawnCmd router (Perform task) = + Native.Scheduler.spawn ( + task + |> andThen (Platform.sendToApp router) + ) diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Time.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Time.elm new file mode 100644 index 0000000..b50cdfe --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Time.elm @@ -0,0 +1,243 @@ +effect module Time where { subscription = MySub } exposing + ( Time + , now, every + , millisecond, second, minute, hour + , inMilliseconds, inSeconds, inMinutes, inHours + ) + +{-| Library for working with time. + +# Time +@docs Time, now, every + +# Units +@docs millisecond, second, minute, hour, + inMilliseconds, inSeconds, inMinutes, inHours + +-} + + +import Basics exposing (..) +import Dict +import List exposing ((::)) +import Maybe exposing (Maybe(..)) +import Native.Scheduler +import Native.Time +import Platform +import Platform.Sub exposing (Sub) +import Task exposing (Task) + + + +-- TIMES + + +{-| Type alias to make it clearer when you are working with time values. +Using the `Time` helpers like `second` and `inSeconds` instead of raw numbers +is very highly recommended. +-} +type alias Time = Float + + +{-| Get the `Time` at the moment when this task is run. +-} +now : Task x Time +now = + Native.Time.now + + +{-| Subscribe to the current time. First you provide an interval describing how +frequently you want updates. Second, you give a tagger that turns a time into a +message for your `update` function. So if you want to hear about the current +time every second, you would say something like this: + + type Msg = Tick Time | ... + + subscriptions model = + every second Tick + +Check out the [Elm Architecture Tutorial][arch] for more info on how +subscriptions work. + +[arch]: https://github.com/evancz/elm-architecture-tutorial/ + +**Note:** this function is not for animation! You need to use something based +on `requestAnimationFrame` to get smooth animations. This is based on +`setInterval` which is better for recurring tasks like “check on something +every 30 seconds”. +-} +every : Time -> (Time -> msg) -> Sub msg +every interval tagger = + subscription (Every interval tagger) + + + +-- UNITS + + +{-| Units of time, making it easier to specify things like a half-second +`(500 * millisecond)` without remembering Elm’s underlying units of time. +-} +millisecond : Time +millisecond = + 1 + + +{-|-} +second : Time +second = + 1000 * millisecond + + +{-|-} +minute : Time +minute = + 60 * second + + +{-|-} +hour : Time +hour = + 60 * minute + + +{-|-} +inMilliseconds : Time -> Float +inMilliseconds t = + t + + +{-|-} +inSeconds : Time -> Float +inSeconds t = + t / second + + +{-|-} +inMinutes : Time -> Float +inMinutes t = + t / minute + + +{-|-} +inHours : Time -> Float +inHours t = + t / hour + + + +-- SUBSCRIPTIONS + + +type MySub msg = + Every Time (Time -> msg) + + +subMap : (a -> b) -> MySub a -> MySub b +subMap f (Every interval tagger) = + Every interval (f << tagger) + + + +-- EFFECT MANAGER + + +type alias State msg = + { taggers : Taggers msg + , processes : Processes + } + + +type alias Processes = + Dict.Dict Time Platform.ProcessId + + +type alias Taggers msg = + Dict.Dict Time (List (Time -> msg)) + + +init : Task Never (State msg) +init = + Task.succeed (State Dict.empty Dict.empty) + + +onEffects : Platform.Router msg Time -> List (MySub msg) -> State msg -> Task Never (State msg) +onEffects router subs {processes} = + let + newTaggers = + List.foldl addMySub Dict.empty subs + + leftStep interval taggers (spawnList, existingDict, killTask) = + (interval :: spawnList, existingDict, killTask) + + bothStep interval taggers id (spawnList, existingDict, killTask) = + (spawnList, Dict.insert interval id existingDict, killTask) + + rightStep _ id (spawnList, existingDict, killTask) = + ( spawnList + , existingDict + , Native.Scheduler.kill id + |> Task.andThen (\_ -> killTask) + ) + + (spawnList, existingDict, killTask) = + Dict.merge + leftStep + bothStep + rightStep + newTaggers + processes + ([], Dict.empty, Task.succeed ()) + in + killTask + |> Task.andThen (\_ -> spawnHelp router spawnList existingDict) + |> Task.andThen (\newProcesses -> Task.succeed (State newTaggers newProcesses)) + + +addMySub : MySub msg -> Taggers msg -> Taggers msg +addMySub (Every interval tagger) state = + case Dict.get interval state of + Nothing -> + Dict.insert interval [tagger] state + + Just taggers -> + Dict.insert interval (tagger :: taggers) state + + +spawnHelp : Platform.Router msg Time -> List Time -> Processes -> Task.Task x Processes +spawnHelp router intervals processes = + case intervals of + [] -> + Task.succeed processes + + interval :: rest -> + let + spawnTimer = + Native.Scheduler.spawn (setInterval interval (Platform.sendToSelf router interval)) + + spawnRest id = + spawnHelp router rest (Dict.insert interval id processes) + in + spawnTimer + |> Task.andThen spawnRest + + +onSelfMsg : Platform.Router msg Time -> Time -> State msg -> Task Never (State msg) +onSelfMsg router interval state = + case Dict.get interval state.taggers of + Nothing -> + Task.succeed state + + Just taggers -> + let + tellTaggers time = + Task.sequence (List.map (\tagger -> Platform.sendToApp router (tagger time)) taggers) + in + now + |> Task.andThen tellTaggers + |> Task.andThen (\_ -> Task.succeed state) + + +setInterval : Time -> Task Never () -> Task x Never +setInterval = + Native.Time.setInterval_ diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Tuple.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Tuple.elm new file mode 100644 index 0000000..ab4c401 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/src/Tuple.elm @@ -0,0 +1,61 @@ +module Tuple exposing + ( first, second + , mapFirst, mapSecond + ) + +{-| Some helpers for working with 2-tuples. + +**Note:** For larger chunks of data, it is best to switch to using records. So +instead of representing a 3D point as `(3,4,5)` and wondering why there are no +helper functions, represent it as `{ x = 3, y = 4, z = 5 }` and use all the +built-in syntax for records. + +@docs first, second, mapFirst, mapSecond + +-} + + + +{-| Extract the first value from a tuple. + + first (3, 4) == 3 + first ("john", "doe") == "john" +-} +first : (a1, a2) -> a1 +first (x,_) = + x + + +{-| Extract the second value from a tuple. + + second (3, 4) == 4 + second ("john", "doe") == "doe" +-} +second : (a1, a2) -> a2 +second (_,y) = + y + + +{-| Transform the first value in a tuple. + + import String + + mapFirst String.reverse ("stressed", 16) == ("desserts", 16) + mapFirst String.length ("stressed", 16) == (8, 16) +-} +mapFirst : (a -> b) -> (a, a2) -> (b, a2) +mapFirst func (x,y) = + (func x, y) + + +{-| Transform the second value in a tuple. + + import String + + mapSecond sqrt ("stressed", 16) == ("stressed", 4) + mapSecond (\x -> x + 1) ("stressed", 16) == ("stressed", 17) +-} +mapSecond : (a -> b) -> (a1, a) -> (a1, b) +mapSecond func (x,y) = + (x, func y) + diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Main.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Main.elm new file mode 100644 index 0000000..0fb81c9 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Main.elm @@ -0,0 +1,50 @@ +port module Main exposing (..) + +import Basics exposing (..) +import Task exposing (..) +import Test exposing (..) +import Platform.Cmd exposing (Cmd) +import Json.Decode exposing (Value) +import Test.Runner.Node exposing (run, TestProgram) +import Test.Array as Array +import Test.Basics as Basics +import Test.Bitwise as Bitwise +import Test.Char as Char +import Test.CodeGen as CodeGen +import Test.Dict as Dict +import Test.Maybe as Maybe +import Test.Equality as Equality +import Test.Json as Json +import Test.List as List +import Test.Result as Result +import Test.Set as Set +import Test.String as String +import Test.Regex as Regex + + +tests : Test +tests = + describe "Elm Standard Library Tests" + [ Array.tests + , Basics.tests + , Bitwise.tests + , Char.tests + , CodeGen.tests + , Dict.tests + , Equality.tests + , Json.tests + , List.tests + , Result.tests + , Set.tests + , String.tests + , Regex.tests + , Maybe.tests + ] + + +main : TestProgram +main = + run emit tests + + +port emit : ( String, Value ) -> Cmd msg diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Array.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Array.elm new file mode 100644 index 0000000..e32b49d --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Array.elm @@ -0,0 +1,120 @@ +module Test.Array exposing (tests) + +import Array +import Basics exposing (..) +import List +import List exposing ((::)) +import Maybe exposing (..) +import Native.Array +import Test exposing (..) +import Expect + + +mergeSplit : Int -> Array.Array a -> Array.Array a +mergeSplit n arr = + let + left = + Array.slice 0 n arr + + right = + Array.slice n (Array.length arr) arr + in + Array.append left right + + +holeArray : Array.Array Int +holeArray = + List.foldl mergeSplit (Array.fromList (List.range 0 100)) (List.range 0 100) + + +mapArray : Array.Array a -> Array.Array a +mapArray array = + Array.indexedMap + (\i el -> + case (Array.get i array) of + Just x -> + x + + Nothing -> + el + ) + array + + +tests : Test +tests = + let + creationTests = + describe "Creation" + [ test "empty" <| \() -> Expect.equal Array.empty (Array.fromList []) + , test "initialize" <| \() -> Expect.equal (Array.initialize 4 identity) (Array.fromList [ 0, 1, 2, 3 ]) + , test "initialize 2" <| \() -> Expect.equal (Array.initialize 4 (\n -> n * n)) (Array.fromList [ 0, 1, 4, 9 ]) + , test "initialize 3" <| \() -> Expect.equal (Array.initialize 4 (always 0)) (Array.fromList [ 0, 0, 0, 0 ]) + , test "initialize Empty" <| \() -> Expect.equal (Array.initialize 0 identity) Array.empty + , test "initialize 4" <| \() -> Expect.equal (Array.initialize 2 (always 0)) (Array.fromList [ 0, 0 ]) + , test "initialize negative" <| \() -> Expect.equal (Array.initialize -1 identity) Array.empty + , test "repeat" <| \() -> Expect.equal (Array.repeat 5 40) (Array.fromList [ 40, 40, 40, 40, 40 ]) + , test "repeat 2" <| \() -> Expect.equal (Array.repeat 5 0) (Array.fromList [ 0, 0, 0, 0, 0 ]) + , test "repeat 3" <| \() -> Expect.equal (Array.repeat 3 "cat") (Array.fromList [ "cat", "cat", "cat" ]) + , test "fromList" <| \() -> Expect.equal (Array.fromList []) Array.empty + ] + + basicsTests = + describe "Basics" + [ test "length" <| \() -> Expect.equal 3 (Array.length (Array.fromList [ 1, 2, 3 ])) + , test "length - Long" <| \() -> Expect.equal 10000 (Array.length (Array.repeat 10000 0)) + , test "push" <| \() -> Expect.equal (Array.fromList [ 1, 2, 3 ]) (Array.push 3 (Array.fromList [ 1, 2 ])) + , test "append" <| \() -> Expect.equal [ 42, 42, 81, 81, 81 ] (Array.toList (Array.append (Array.repeat 2 42) (Array.repeat 3 81))) + , test "appendEmpty 1" <| \() -> Expect.equal (List.range 1 33) (Array.toList (Array.append Array.empty (Array.fromList <| List.range 1 33))) + , test "appendEmpty 2" <| \() -> Expect.equal (List.range 1 33) (Array.toList (Array.append (Array.fromList <| List.range 1 33) Array.empty)) + , test "appendSmall 1" <| \() -> Expect.equal (List.range 1 33) (Array.toList (Array.append (Array.fromList <| List.range 1 30) (Array.fromList <| List.range 31 33))) + , test "appendSmall 2" <| \() -> Expect.equal (List.range 1 33) (Array.toList (Array.append (Array.fromList <| List.range 1 3) (Array.fromList <| List.range 4 33))) + , test "appendAndSlice" <| \() -> Expect.equal (List.range 0 100) (Array.toList holeArray) + ] + + getAndSetTests = + describe "Get and Set" + [ test "get" <| \() -> Expect.equal (Just 2) (Array.get 1 (Array.fromList [ 3, 2, 1 ])) + , test "get 2" <| \() -> Expect.equal Nothing (Array.get 5 (Array.fromList [ 3, 2, 1 ])) + , test "get 3" <| \() -> Expect.equal Nothing (Array.get -1 (Array.fromList [ 3, 2, 1 ])) + , test "set" <| \() -> Expect.equal (Array.fromList [ 1, 7, 3 ]) (Array.set 1 7 (Array.fromList [ 1, 2, 3 ])) + ] + + takingArraysApartTests = + describe "Taking Arrays Apart" + [ test "toList" <| \() -> Expect.equal [ 3, 5, 8 ] (Array.toList (Array.fromList [ 3, 5, 8 ])) + , test "toIndexedList" <| \() -> Expect.equal [ ( 0, "cat" ), ( 1, "dog" ) ] (Array.toIndexedList (Array.fromList [ "cat", "dog" ])) + , test "slice 1" <| \() -> Expect.equal (Array.fromList [ 0, 1, 2 ]) (Array.slice 0 3 (Array.fromList [ 0, 1, 2, 3, 4 ])) + , test "slice 2" <| \() -> Expect.equal (Array.fromList [ 1, 2, 3 ]) (Array.slice 1 4 (Array.fromList [ 0, 1, 2, 3, 4 ])) + , test "slice 3" <| \() -> Expect.equal (Array.fromList [ 1, 2, 3 ]) (Array.slice 1 -1 (Array.fromList [ 0, 1, 2, 3, 4 ])) + , test "slice 4" <| \() -> Expect.equal (Array.fromList [ 2 ]) (Array.slice -3 -2 (Array.fromList [ 0, 1, 2, 3, 4 ])) + , test "slice 5" <| \() -> Expect.equal 63 (Array.length <| Array.slice 65 (65 + 63) <| Array.fromList (List.range 1 200)) + ] + + mappingAndFoldingTests = + describe "Mapping and Folding" + [ test "map" <| \() -> Expect.equal (Array.fromList [ 1, 2, 3 ]) (Array.map sqrt (Array.fromList [ 1, 4, 9 ])) + , test "indexedMap 1" <| \() -> Expect.equal (Array.fromList [ 0, 5, 10 ]) (Array.indexedMap (*) (Array.fromList [ 5, 5, 5 ])) + , test "indexedMap 2" <| \() -> Expect.equal (List.range 0 99) (Array.toList (Array.indexedMap always (Array.repeat 100 0))) + , test "large indexed map" <| \() -> Expect.equal (List.range 0 <| 32768 - 1) (Array.toList <| mapArray <| Array.initialize 32768 identity) + , test "foldl 1" <| \() -> Expect.equal [ 3, 2, 1 ] (Array.foldl (::) [] (Array.fromList [ 1, 2, 3 ])) + , test "foldl 2" <| \() -> Expect.equal 33 (Array.foldl (+) 0 (Array.repeat 33 1)) + , test "foldr 1" <| \() -> Expect.equal 15 (Array.foldr (+) 0 (Array.repeat 3 5)) + , test "foldr 2" <| \() -> Expect.equal [ 1, 2, 3 ] (Array.foldr (::) [] (Array.fromList [ 1, 2, 3 ])) + , test "foldr 3" <| \() -> Expect.equal 53 (Array.foldr (-) 54 (Array.fromList [ 10, 11 ])) + , test "filter" <| \() -> Expect.equal (Array.fromList [ 2, 4, 6 ]) (Array.filter (\x -> x % 2 == 0) (Array.fromList <| List.range 1 6)) + ] + + nativeTests = + describe "Conversion to JS Arrays" + [ test "jsArrays" <| \() -> Expect.equal (Array.fromList <| List.range 1 1100) (Native.Array.fromJSArray (Native.Array.toJSArray (Array.fromList <| List.range 1 1100))) + ] + in + describe "Array" + [ creationTests + , basicsTests + , getAndSetTests + , takingArraysApartTests + , mappingAndFoldingTests + , nativeTests + ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Basics.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Basics.elm new file mode 100644 index 0000000..56742cb --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Basics.elm @@ -0,0 +1,220 @@ +module Test.Basics exposing (tests) + +import Array +import Tuple exposing (first, second) +import Basics exposing (..) +import Date +import Set +import Dict +import Test exposing (..) +import Expect +import List +import String + + +tests : Test +tests = + let + comparison = + describe "Comparison" + [ test "max" <| \() -> Expect.equal 42 (max 32 42) + , test "min" <| \() -> Expect.equal 42 (min 91 42) + , test "clamp low" <| \() -> Expect.equal 10 (clamp 10 20 5) + , test "clamp mid" <| \() -> Expect.equal 15 (clamp 10 20 15) + , test "clamp high" <| \() -> Expect.equal 20 (clamp 10 20 25) + , test "5 < 6" <| \() -> Expect.equal True (5 < 6) + , test "6 < 5" <| \() -> Expect.equal False (6 < 5) + , test "6 < 6" <| \() -> Expect.equal False (6 < 6) + , test "5 > 6" <| \() -> Expect.equal False (5 > 6) + , test "6 > 5" <| \() -> Expect.equal True (6 > 5) + , test "6 > 6" <| \() -> Expect.equal False (6 > 6) + , test "5 <= 6" <| \() -> Expect.equal True (5 <= 6) + , test "6 <= 5" <| \() -> Expect.equal False (6 <= 5) + , test "6 <= 6" <| \() -> Expect.equal True (6 <= 6) + , test "compare \"A\" \"B\"" <| \() -> Expect.equal LT (compare "A" "B") + , test "compare 'f' 'f'" <| \() -> Expect.equal EQ (compare 'f' 'f') + , test "compare (1, 2, 3, 4, 5, 6) (0, 1, 2, 3, 4, 5)" <| \() -> Expect.equal GT (compare ( 1, 2, 3, 4, 5, 6 ) ( 0, 1, 2, 3, 4, 5 )) + , test "compare ['a'] ['b']" <| \() -> Expect.equal LT (compare [ 'a' ] [ 'b' ]) + , test "array equality" <| \() -> Expect.equal (Array.fromList [ 1, 1, 1, 1 ]) (Array.repeat 4 1) + , test "set equality" <| \() -> Expect.equal (Set.fromList [ 1, 2 ]) (Set.fromList [ 2, 1 ]) + , test "dict equality" <| \() -> Expect.equal (Dict.fromList [ ( 1, 1 ), ( 2, 2 ) ]) (Dict.fromList [ ( 2, 2 ), ( 1, 1 ) ]) + , test "char equality" <| \() -> Expect.notEqual '0' '饑' + , test "date equality" <| \() -> Expect.equal (Date.fromString "2/7/1992") (Date.fromString "2/7/1992") + , test "date equality" <| \() -> Expect.notEqual (Date.fromString "11/16/1995") (Date.fromString "2/7/1992") + ] + + toStringTests = + describe "toString Tests" + [ test "toString Int" <| \() -> Expect.equal "42" (toString 42) + , test "toString Float" <| \() -> Expect.equal "42.52" (toString 42.52) + , test "toString Char" <| \() -> Expect.equal "'c'" (toString 'c') + , test "toString Char single quote" <| \() -> Expect.equal "'\\''" (toString '\'') + , test "toString Char double quote" <| \() -> Expect.equal "'\"'" (toString '"') + , test "toString String single quote" <| \() -> Expect.equal "\"not 'escaped'\"" (toString "not 'escaped'") + , test "toString String double quote" <| \() -> Expect.equal "\"are \\\"escaped\\\"\"" (toString "are \"escaped\"") + , test "toString record" <| \() -> Expect.equal "{ field = [0] }" (toString { field = [ 0 ] }) + -- TODO + --, test "toString record, special case" <| \() -> Expect.equal "{ ctor = [0] }" (toString { ctor = [ 0 ] }) + ] + + trigTests = + describe "Trigonometry Tests" + [ test "radians 0" <| \() -> Expect.equal 0 (radians 0) + , test "radians positive" <| \() -> Expect.equal 5 (radians 5) + , test "radians negative" <| \() -> Expect.equal -5 (radians -5) + , test "degrees 0" <| \() -> Expect.equal 0 (degrees 0) + , test "degrees 90" <| \() -> Expect.lessThan 0.01 (abs (1.57 - degrees 90)) + -- This should test to enough precision to know if anything's breaking + , test "degrees -145" <| \() -> Expect.lessThan 0.01 (abs (-2.53 - degrees -145)) + -- This should test to enough precision to know if anything's breaking + , test "turns 0" <| \() -> Expect.equal 0 (turns 0) + , test "turns 8" <| \() -> Expect.lessThan 0.01 (abs (50.26 - turns 8)) + -- This should test to enough precision to know if anything's breaking + , test "turns -133" <| \() -> Expect.lessThan 0.01 (abs (-835.66 - turns -133)) + -- This should test to enough precision to know if anything's breaking + , test "fromPolar (0, 0)" <| \() -> Expect.equal ( 0, 0 ) (fromPolar ( 0, 0 )) + , test "fromPolar (1, 0)" <| \() -> Expect.equal ( 1, 0 ) (fromPolar ( 1, 0 )) + , test "fromPolar (0, 1)" <| \() -> Expect.equal ( 0, 0 ) (fromPolar ( 0, 1 )) + , test "fromPolar (1, 1)" <| + \() -> + Expect.equal True + (let + ( x, y ) = + fromPolar ( 1, 1 ) + in + 0.54 - x < 0.01 && 0.84 - y < 0.01 + ) + , test "toPolar (0, 0)" <| \() -> Expect.equal ( 0, 0 ) (toPolar ( 0, 0 )) + , test "toPolar (1, 0)" <| \() -> Expect.equal ( 1, 0 ) (toPolar ( 1, 0 )) + , test "toPolar (0, 1)" <| + \() -> + Expect.equal True + (let + ( r, theta ) = + toPolar ( 0, 1 ) + in + r == 1 && abs (1.57 - theta) < 0.01 + ) + , test "toPolar (1, 1)" <| + \() -> + Expect.equal True + (let + ( r, theta ) = + toPolar ( 1, 1 ) + in + abs (1.41 - r) < 0.01 && abs (0.78 - theta) < 0.01 + ) + , test "cos" <| \() -> Expect.equal 1 (cos 0) + , test "sin" <| \() -> Expect.equal 0 (sin 0) + , test "tan" <| \() -> Expect.lessThan 0.01 (abs (12.67 - tan 17.2)) + , test "acos" <| \() -> Expect.lessThan 0.01 (abs (3.14 - acos -1)) + , test "asin" <| \() -> Expect.lessThan 0.01 (abs (0.3 - asin 0.3)) + , test "atan" <| \() -> Expect.lessThan 0.01 (abs (1.57 - atan 4567.8)) + , test "atan2" <| \() -> Expect.lessThan 0.01 (abs (1.55 - atan2 36 0.65)) + , test "pi" <| \() -> Expect.lessThan 0.01 (abs (3.14 - pi)) + ] + + basicMathTests = + describe "Basic Math Tests" + [ test "add float" <| \() -> Expect.equal 159 (155.6 + 3.4) + , test "add int" <| \() -> Expect.equal 17 ((round 10) + (round 7)) + , test "subtract float" <| \() -> Expect.equal -6.3 (1 - 7.3) + , test "subtract int" <| \() -> Expect.equal 1130 ((round 9432) - (round 8302)) + , test "multiply float" <| \() -> Expect.equal 432 (96 * 4.5) + , test "multiply int" <| \() -> Expect.equal 90 ((round 10) * (round 9)) + , test "divide float" <| \() -> Expect.equal 13.175 (527 / 40) + , test "divide int" <| \() -> Expect.equal 23 (70 // 3) + , test "2 |> rem 7" <| \() -> Expect.equal 1 (2 |> rem 7) + , test "4 |> rem -1" <| \() -> Expect.equal -1 (4 |> rem -1) + , test "7 % 2" <| \() -> Expect.equal 1 (7 % 2) + , test "-1 % 4" <| \() -> Expect.equal 3 (-1 % 4) + , test "3^2" <| \() -> Expect.equal 9 (3 ^ 2) + , test "sqrt" <| \() -> Expect.equal 9 (sqrt 81) + , test "negate 42" <| \() -> Expect.equal -42 (negate 42) + , test "negate -42" <| \() -> Expect.equal 42 (negate -42) + , test "negate 0" <| \() -> Expect.equal 0 (negate 0) + , test "abs -25" <| \() -> Expect.equal 25 (abs -25) + , test "abs 76" <| \() -> Expect.equal 76 (abs 76) + , test "logBase 10 100" <| \() -> Expect.equal 2 (logBase 10 100) + , test "logBase 2 256" <| \() -> Expect.equal 8 (logBase 2 256) + , test "e" <| \() -> Expect.lessThan 0.01 (abs (2.72 - e)) + ] + + booleanTests = + describe "Boolean Tests" + [ test "False && False" <| \() -> Expect.equal False (False && False) + , test "False && True" <| \() -> Expect.equal False (False && True) + , test "True && False" <| \() -> Expect.equal False (True && False) + , test "True && True" <| \() -> Expect.equal True (True && True) + , test "False || False" <| \() -> Expect.equal False (False || False) + , test "False || True" <| \() -> Expect.equal True (False || True) + , test "True || False" <| \() -> Expect.equal True (True || False) + , test "True || True" <| \() -> Expect.equal True (True || True) + , test "xor False False" <| \() -> Expect.equal False (xor False False) + , test "xor False True" <| \() -> Expect.equal True (xor False True) + , test "xor True False" <| \() -> Expect.equal True (xor True False) + , test "xor True True" <| \() -> Expect.equal False (xor True True) + , test "not True" <| \() -> Expect.equal False (not True) + , test "not False" <| \() -> Expect.equal True (not False) + ] + + conversionTests = + describe "Conversion Tests" + [ test "round 0.6" <| \() -> Expect.equal 1 (round 0.6) + , test "round 0.4" <| \() -> Expect.equal 0 (round 0.4) + , test "round 0.5" <| \() -> Expect.equal 1 (round 0.5) + , test "truncate -2367.9267" <| \() -> Expect.equal -2367 (truncate -2367.9267) + , test "floor -2367.9267" <| \() -> Expect.equal -2368 (floor -2367.9267) + , test "ceiling 37.2" <| \() -> Expect.equal 38 (ceiling 37.2) + , test "toFloat 25" <| \() -> Expect.equal 25 (toFloat 25) + ] + + miscTests = + describe "Miscellaneous Tests" + [ test "isNaN (0/0)" <| \() -> Expect.equal True (isNaN (0 / 0)) + , test "isNaN (sqrt -1)" <| \() -> Expect.equal True (isNaN (sqrt -1)) + , test "isNaN (1/0)" <| \() -> Expect.equal False (isNaN (1 / 0)) + , test "isNaN 1" <| \() -> Expect.equal False (isNaN 1) + , test "isInfinite (0/0)" <| \() -> Expect.equal False (isInfinite (0 / 0)) + , test "isInfinite (sqrt -1)" <| \() -> Expect.equal False (isInfinite (sqrt -1)) + , test "isInfinite (1/0)" <| \() -> Expect.equal True (isInfinite (1 / 0)) + , test "isInfinite 1" <| \() -> Expect.equal False (isInfinite 1) + , test "\"hello\" ++ \"world\"" <| \() -> Expect.equal "helloworld" ("hello" ++ "world") + , test "[1, 1, 2] ++ [3, 5, 8]" <| \() -> Expect.equal [ 1, 1, 2, 3, 5, 8 ] ([ 1, 1, 2 ] ++ [ 3, 5, 8 ]) + , test "first (1, 2)" <| \() -> Expect.equal 1 (first ( 1, 2 )) + , test "second (1, 2)" <| \() -> Expect.equal 2 (second ( 1, 2 )) + ] + + higherOrderTests = + describe "Higher Order Helpers" + [ test "identity 'c'" <| \() -> Expect.equal 'c' (identity 'c') + , test "always 42 ()" <| \() -> Expect.equal 42 (always 42 ()) + , test "<|" <| \() -> Expect.equal 9 (identity <| 3 + 6) + , test "|>" <| \() -> Expect.equal 9 (3 + 6 |> identity) + , test "<<" <| \() -> Expect.equal True (not << xor True <| True) + , test "<<" <| \() -> Expect.equal True (not << xor True <| True) + , describe ">>" + [ test "with xor" <| + \() -> + (True |> xor True >> not) + |> Expect.equal True + , test "with a record accessor" <| + \() -> + [ { foo = "NaS", bar = "baz" } ] + |> List.map (.foo >> String.reverse) + |> Expect.equal [ "SaN" ] + ] + , test "flip" <| \() -> Expect.equal 10 ((flip (//)) 2 20) + , test "curry" <| \() -> Expect.equal 1 ((curry (\( a, b ) -> a + b)) -5 6) + , test "uncurry" <| \() -> Expect.equal 1 ((uncurry (+)) ( -5, 6 )) + ] + in + describe "Basics" + [ comparison + , toStringTests + , trigTests + , basicMathTests + , booleanTests + , miscTests + , higherOrderTests + ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Bitwise.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Bitwise.elm new file mode 100644 index 0000000..844ebba --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Bitwise.elm @@ -0,0 +1,51 @@ +module Test.Bitwise exposing (tests) + +import Basics exposing (..) +import Bitwise +import Test exposing (..) +import Expect + + +tests : Test +tests = + describe "Bitwise" + [ describe "and" + [ test "and with 32 bit integers" <| \() -> Expect.equal 1 (Bitwise.and 5 3) + , test "and with 0 as first argument" <| \() -> Expect.equal 0 (Bitwise.and 0 1450) + , test "and with 0 as second argument" <| \() -> Expect.equal 0 (Bitwise.and 274 0) + , test "and with -1 as first argument" <| \() -> Expect.equal 2671 (Bitwise.and -1 2671) + , test "and with -1 as second argument" <| \() -> Expect.equal 96 (Bitwise.and 96 -1) + ] + , describe "or" + [ test "or with 32 bit integers" <| \() -> Expect.equal 15 (Bitwise.or 9 14) + , test "or with 0 as first argument" <| \() -> Expect.equal 843 (Bitwise.or 0 843) + , test "or with 0 as second argument" <| \() -> Expect.equal 19 (Bitwise.or 19 0) + , test "or with -1 as first argument" <| \() -> Expect.equal -1 (Bitwise.or -1 2360) + , test "or with -1 as second argument" <| \() -> Expect.equal -1 (Bitwise.or 3 -1) + ] + , describe "xor" + [ test "xor with 32 bit integers" <| \() -> Expect.equal 604 (Bitwise.xor 580 24) + , test "xor with 0 as first argument" <| \() -> Expect.equal 56 (Bitwise.xor 0 56) + , test "xor with 0 as second argument" <| \() -> Expect.equal -268 (Bitwise.xor -268 0) + , test "xor with -1 as first argument" <| \() -> Expect.equal -25 (Bitwise.xor -1 24) + , test "xor with -1 as second argument" <| \() -> Expect.equal 25601 (Bitwise.xor -25602 -1) + ] + , describe "complement" + [ test "complement a positive" <| \() -> Expect.equal -9 (Bitwise.complement 8) + , test "complement a negative" <| \() -> Expect.equal 278 (Bitwise.complement -279) + ] + , describe "shiftLeftBy" + [ test "8 |> shiftLeftBy 1 == 16" <| \() -> Expect.equal 16 (8 |> Bitwise.shiftLeftBy 1) + , test "8 |> shiftLeftby 2 == 32" <| \() -> Expect.equal 32 (8 |> Bitwise.shiftLeftBy 2) + ] + , describe "shiftRightBy" + [ test "32 |> shiftRight 1 == 16" <| \() -> Expect.equal 16 (32 |> Bitwise.shiftRightBy 1) + , test "32 |> shiftRight 2 == 8" <| \() -> Expect.equal 8 (32 |> Bitwise.shiftRightBy 2) + , test "-32 |> shiftRight 1 == -16" <| \() -> Expect.equal -16 (-32 |> Bitwise.shiftRightBy 1) + ] + , describe "shiftRightZfBy" + [ test "32 |> shiftRightZfBy 1 == 16" <| \() -> Expect.equal 16 (32 |> Bitwise.shiftRightZfBy 1) + , test "32 |> shiftRightZfBy 2 == 8" <| \() -> Expect.equal 8 (32 |> Bitwise.shiftRightZfBy 2) + , test "-32 |> shiftRightZfBy 1 == 2147483632" <| \() -> Expect.equal 2147483632 (-32 |> Bitwise.shiftRightZfBy 1) + ] + ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Char.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Char.elm new file mode 100644 index 0000000..598aae3 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Char.elm @@ -0,0 +1,113 @@ +module Test.Char exposing (tests) + +import Basics exposing (..) +import Char exposing (..) +import List +import Test exposing (..) +import Expect + + +lower = + [ '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' ] + + +upper = + [ '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' ] + + +dec = + [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ] + + +oct = + List.take 8 dec + + +hexLower = + List.take 6 lower + + +hexUpper = + List.take 6 upper + + +hex = + List.append hexLower hexUpper |> List.append dec + + +lowerCodes = + List.range 97 (97 + List.length lower - 1) + + +upperCodes = + List.range 65 (65 + List.length upper - 1) + + +decCodes = + List.range 48 (48 + List.length dec - 1) + + +oneOf : List a -> a -> Bool +oneOf = + flip List.member + + +tests : Test +tests = + describe "Char" + [ describe "toCode" + [ test "a-z" <| \() -> Expect.equal (lowerCodes) (List.map toCode lower) + , test "A-Z" <| \() -> Expect.equal (upperCodes) (List.map toCode upper) + , test "0-9" <| \() -> Expect.equal (decCodes) (List.map toCode dec) + ] + , describe "fromCode" + [ test "a-z" <| \() -> Expect.equal (lower) (List.map fromCode lowerCodes) + , test "A-Z" <| \() -> Expect.equal (upper) (List.map fromCode upperCodes) + , test "0-9" <| \() -> Expect.equal (dec) (List.map fromCode decCodes) + ] + , describe "toLocaleLower" + [ test "a-z" <| \() -> Expect.equal (lower) (List.map toLocaleLower lower) + , test "A-Z" <| \() -> Expect.equal (lower) (List.map toLocaleLower upper) + , test "0-9" <| \() -> Expect.equal (dec) (List.map toLocaleLower dec) + ] + , describe "toLocaleUpper" + [ test "a-z" <| \() -> Expect.equal (upper) (List.map toLocaleUpper lower) + , test "A-Z" <| \() -> Expect.equal (upper) (List.map toLocaleUpper upper) + , test "0-9" <| \() -> Expect.equal (dec) (List.map toLocaleUpper dec) + ] + , describe "toLower" + [ test "a-z" <| \() -> Expect.equal (lower) (List.map toLower lower) + , test "A-Z" <| \() -> Expect.equal (lower) (List.map toLower upper) + , test "0-9" <| \() -> Expect.equal (dec) (List.map toLower dec) + ] + , describe "toUpper" + [ test "a-z" <| \() -> Expect.equal (upper) (List.map toUpper lower) + , test "A-Z" <| \() -> Expect.equal (upper) (List.map toUpper upper) + , test "0-9" <| \() -> Expect.equal (dec) (List.map toUpper dec) + ] + , describe "isLower" + [ test "a-z" <| \() -> Expect.equal (True) (List.all isLower lower) + , test "A-Z" <| \() -> Expect.equal (False) (List.any isLower upper) + , test "0-9" <| \() -> Expect.equal (False) (List.any isLower dec) + ] + , describe "isUpper" + [ test "a-z" <| \() -> Expect.equal (False) (List.any isUpper lower) + , test "A-Z" <| \() -> Expect.equal (True) (List.all isUpper upper) + , test "0-9" <| \() -> Expect.equal (False) (List.any isUpper dec) + ] + , describe "isDigit" + [ test "a-z" <| \() -> Expect.equal (False) (List.any isDigit lower) + , test "A-Z" <| \() -> Expect.equal (False) (List.any isDigit upper) + , test "0-9" <| \() -> Expect.equal (True) (List.all isDigit dec) + ] + , describe "isHexDigit" + [ test "a-z" <| \() -> Expect.equal (List.map (oneOf hex) lower) (List.map isHexDigit lower) + , test "A-Z" <| \() -> Expect.equal (List.map (oneOf hex) upper) (List.map isHexDigit upper) + , test "0-9" <| \() -> Expect.equal (True) (List.all isHexDigit dec) + ] + , describe "isOctDigit" + [ test "a-z" <| \() -> Expect.equal (False) (List.any isOctDigit lower) + , test "A-Z" <| \() -> Expect.equal (False) (List.any isOctDigit upper) + , test "0-9" <| \() -> Expect.equal (List.map (oneOf oct) dec) (List.map isOctDigit dec) + ] + ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/CodeGen.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/CodeGen.elm new file mode 100644 index 0000000..4a89c63 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/CodeGen.elm @@ -0,0 +1,109 @@ +module Test.CodeGen exposing (tests) + +import Basics exposing (..) +import Test exposing (..) +import Expect +import Maybe +import Maybe exposing (..) + + +type Wrapper a + = Wrapper a + + +caseUnderscore : Maybe number -> number +caseUnderscore m_ = + case m_ of + Just x -> + x + + Nothing -> + 0 + + +patternUnderscore : number +patternUnderscore = + case Just 42 of + Just x_ -> + x_ + + Nothing -> + 0 + + +letQualified : number +letQualified = + let + (Wrapper x) = + Wrapper 42 + in + x + + +caseQualified : number +caseQualified = + case Just 42 of + Maybe.Just x -> + x + + Nothing -> + 0 + + +caseScope : String +caseScope = + case "Not this one!" of + string -> + case "Hi" of + string -> + string + + +tests : Test +tests = + let + -- We don't strictly speaking need annotations in this let-expression, + -- but having these here exercises the parser to avoid regressions like + -- https://github.com/elm-lang/elm-compiler/issues/1535 + underscores : Test + underscores = + describe "Underscores" + [ test "case" <| \() -> Expect.equal 42 (caseUnderscore (Just 42)) + , test "pattern" <| \() -> Expect.equal 42 patternUnderscore + ] + + qualifiedPatterns : Test + qualifiedPatterns = + describe "Qualified Patterns" + [ test "let" <| \() -> Expect.equal 42 letQualified + , test "case" <| \() -> Expect.equal 42 caseQualified + ] + + scope : Test + scope = + describe "Scoping" + [ test "case" <| \() -> Expect.equal "Hi" caseScope ] + + hex : Test + hex = + describe "Hex" + [ test "0xFFFFFFFF" <| + \() -> + 0xFFFFFFFF + |> Expect.equal 4294967295 + , test "0xD066F00D" <| + \() -> + 0xD066F00D + |> Expect.equal 3496407053 + , test "0x00" <| + \() -> + 0x00 + |> Expect.equal 0 + ] + in + describe "CodeGen" + [ underscores + , qualifiedPatterns + , scope + , hex + ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Dict.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Dict.elm new file mode 100644 index 0000000..372b2c9 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Dict.elm @@ -0,0 +1,107 @@ +module Test.Dict exposing (tests) + +import Basics exposing (..) +import Dict +import List +import Maybe exposing (..) +import Test exposing (..) +import Expect + + +animals : Dict.Dict String String +animals = + Dict.fromList [ ( "Tom", "cat" ), ( "Jerry", "mouse" ) ] + + +tests : Test +tests = + let + buildTests = + describe "build Tests" + [ test "empty" <| \() -> Expect.equal (Dict.fromList []) (Dict.empty) + , test "singleton" <| \() -> Expect.equal (Dict.fromList [ ( "k", "v" ) ]) (Dict.singleton "k" "v") + , test "insert" <| \() -> Expect.equal (Dict.fromList [ ( "k", "v" ) ]) (Dict.insert "k" "v" Dict.empty) + , test "insert replace" <| \() -> Expect.equal (Dict.fromList [ ( "k", "vv" ) ]) (Dict.insert "k" "vv" (Dict.singleton "k" "v")) + , test "update" <| \() -> Expect.equal (Dict.fromList [ ( "k", "vv" ) ]) (Dict.update "k" (\v -> Just "vv") (Dict.singleton "k" "v")) + , test "update Nothing" <| \() -> Expect.equal Dict.empty (Dict.update "k" (\v -> Nothing) (Dict.singleton "k" "v")) + , test "remove" <| \() -> Expect.equal Dict.empty (Dict.remove "k" (Dict.singleton "k" "v")) + , test "remove not found" <| \() -> Expect.equal (Dict.singleton "k" "v") (Dict.remove "kk" (Dict.singleton "k" "v")) + ] + + queryTests = + describe "query Tests" + [ test "member 1" <| \() -> Expect.equal True (Dict.member "Tom" animals) + , test "member 2" <| \() -> Expect.equal False (Dict.member "Spike" animals) + , test "get 1" <| \() -> Expect.equal (Just "cat") (Dict.get "Tom" animals) + , test "get 2" <| \() -> Expect.equal Nothing (Dict.get "Spike" animals) + , test "size of empty dictionary" <| \() -> Expect.equal 0 (Dict.size Dict.empty) + , test "size of example dictionary" <| \() -> Expect.equal 2 (Dict.size animals) + ] + + combineTests = + describe "combine Tests" + [ test "union" <| \() -> Expect.equal animals (Dict.union (Dict.singleton "Jerry" "mouse") (Dict.singleton "Tom" "cat")) + , test "union collison" <| \() -> Expect.equal (Dict.singleton "Tom" "cat") (Dict.union (Dict.singleton "Tom" "cat") (Dict.singleton "Tom" "mouse")) + , test "intersect" <| \() -> Expect.equal (Dict.singleton "Tom" "cat") (Dict.intersect animals (Dict.singleton "Tom" "cat")) + , test "diff" <| \() -> Expect.equal (Dict.singleton "Jerry" "mouse") (Dict.diff animals (Dict.singleton "Tom" "cat")) + ] + + transformTests = + describe "transform Tests" + [ test "filter" <| \() -> Expect.equal (Dict.singleton "Tom" "cat") (Dict.filter (\k v -> k == "Tom") animals) + , test "partition" <| \() -> Expect.equal ( Dict.singleton "Tom" "cat", Dict.singleton "Jerry" "mouse" ) (Dict.partition (\k v -> k == "Tom") animals) + ] + + mergeTests = + let + insertBoth key leftVal rightVal dict = + Dict.insert key (leftVal ++ rightVal) dict + + s1 = + Dict.empty |> Dict.insert "u1" [ 1 ] + + s2 = + Dict.empty |> Dict.insert "u2" [ 2 ] + + s23 = + Dict.empty |> Dict.insert "u2" [ 3 ] + + b1 = + List.map (\i -> ( i, [ i ] )) (List.range 1 10) |> Dict.fromList + + b2 = + List.map (\i -> ( i, [ i ] )) (List.range 5 15) |> Dict.fromList + + bExpected = + [ ( 1, [ 1 ] ), ( 2, [ 2 ] ), ( 3, [ 3 ] ), ( 4, [ 4 ] ), ( 5, [ 5, 5 ] ), ( 6, [ 6, 6 ] ), ( 7, [ 7, 7 ] ), ( 8, [ 8, 8 ] ), ( 9, [ 9, 9 ] ), ( 10, [ 10, 10 ] ), ( 11, [ 11 ] ), ( 12, [ 12 ] ), ( 13, [ 13 ] ), ( 14, [ 14 ] ), ( 15, [ 15 ] ) ] + in + describe "merge Tests" + [ test "merge empties" <| + \() -> + Expect.equal (Dict.empty) + (Dict.merge Dict.insert insertBoth Dict.insert Dict.empty Dict.empty Dict.empty) + , test "merge singletons in order" <| + \() -> + Expect.equal [ ( "u1", [ 1 ] ), ( "u2", [ 2 ] ) ] + ((Dict.merge Dict.insert insertBoth Dict.insert s1 s2 Dict.empty) |> Dict.toList) + , test "merge singletons out of order" <| + \() -> + Expect.equal [ ( "u1", [ 1 ] ), ( "u2", [ 2 ] ) ] + ((Dict.merge Dict.insert insertBoth Dict.insert s2 s1 Dict.empty) |> Dict.toList) + , test "merge with duplicate key" <| + \() -> + Expect.equal [ ( "u2", [ 2, 3 ] ) ] + ((Dict.merge Dict.insert insertBoth Dict.insert s2 s23 Dict.empty) |> Dict.toList) + , test "partially overlapping" <| + \() -> + Expect.equal bExpected + ((Dict.merge Dict.insert insertBoth Dict.insert b1 b2 Dict.empty) |> Dict.toList) + ] + in + describe "Dict Tests" + [ buildTests + , queryTests + , combineTests + , transformTests + , mergeTests + ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Equality.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Equality.elm new file mode 100644 index 0000000..1737477 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Equality.elm @@ -0,0 +1,34 @@ +module Test.Equality exposing (tests) + +import Basics exposing (..) +import Maybe exposing (..) +import Test exposing (..) +import Expect + + +type Different + = A String + | B (List Int) + + +tests : Test +tests = + let + diffTests = + describe "ADT equality" + [ test "As eq" <| \() -> Expect.equal True (A "a" == A "a") + , test "Bs eq" <| \() -> Expect.equal True (B [ 1 ] == B [ 1 ]) + , test "A left neq" <| \() -> Expect.equal True (A "a" /= B [ 1 ]) + , test "A left neq" <| \() -> Expect.equal True (B [ 1 ] /= A "a") + ] + + recordTests = + describe "Record equality" + [ test "empty same" <| \() -> Expect.equal True ({} == {}) + , test "ctor same" <| \() -> Expect.equal True ({ field = Just 3 } == { field = Just 3 }) + , test "ctor same, special case" <| \() -> Expect.equal True ({ ctor = Just 3 } == { ctor = Just 3 }) + , test "ctor diff" <| \() -> Expect.equal True ({ field = Just 3 } /= { field = Nothing }) + , test "ctor diff, special case" <| \() -> Expect.equal True ({ ctor = Just 3 } /= { ctor = Nothing }) + ] + in + describe "Equality Tests" [ diffTests, recordTests ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Json.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Json.elm new file mode 100644 index 0000000..614a1dd --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Json.elm @@ -0,0 +1,84 @@ +module Test.Json exposing (tests) + +import Basics exposing (..) +import Result exposing (..) +import Json.Decode as Json +import String +import Test exposing (..) +import Expect + + +tests : Test +tests = + describe "Json decode" + [ intTests + , customTests + ] + + +intTests : Test +intTests = + let + testInt val str = + case Json.decodeString Json.int str of + Ok _ -> + Expect.equal val True + + Err _ -> + Expect.equal val False + in + describe "Json decode int" + [ test "whole int" <| \() -> testInt True "4" + , test "-whole int" <| \() -> testInt True "-4" + , test "whole float" <| \() -> testInt True "4.0" + , test "-whole float" <| \() -> testInt True "-4.0" + , test "large int" <| \() -> testInt True "1801439850948" + , test "-large int" <| \() -> testInt True "-1801439850948" + , test "float" <| \() -> testInt False "4.2" + , test "-float" <| \() -> testInt False "-4.2" + , test "Infinity" <| \() -> testInt False "Infinity" + , test "-Infinity" <| \() -> testInt False "-Infinity" + , test "NaN" <| \() -> testInt False "NaN" + , test "-NaN" <| \() -> testInt False "-NaN" + , test "true" <| \() -> testInt False "true" + , test "false" <| \() -> testInt False "false" + , test "string" <| \() -> testInt False "\"string\"" + , test "object" <| \() -> testInt False "{}" + , test "null" <| \() -> testInt False "null" + , test "undefined" <| \() -> testInt False "undefined" + , test "Decoder expects object finds array, was crashing runtime." <| + \() -> + Expect.equal + (Err "Expecting an object but instead got: []") + (Json.decodeString (Json.dict Json.float) "[]") + ] + + +customTests : Test +customTests = + let + jsonString = + """{ "foo": "bar" }""" + + customErrorMessage = + "I want to see this message!" + + myDecoder = + Json.field "foo" Json.string |> Json.andThen (\_ -> Json.fail customErrorMessage) + + assertion = + case Json.decodeString myDecoder jsonString of + Ok _ -> + Expect.fail "expected `customDecoder` to produce a value of type Err, but got Ok" + + Err message -> + if String.contains customErrorMessage message then + Expect.pass + else + Expect.fail <| + "expected `customDecoder` to preserve user's error message '" + ++ customErrorMessage + ++ "', but instead got: " + ++ message + in + test "customDecoder preserves user error messages" <| \() -> assertion diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/List.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/List.elm new file mode 100644 index 0000000..ed26f0f --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/List.elm @@ -0,0 +1,160 @@ +module Test.List exposing (tests) + +import Test exposing (..) +import Expect +import Basics exposing (..) +import Maybe exposing (Maybe(Nothing, Just)) +import List exposing (..) + + +tests : Test +tests = + describe "List Tests" + [ testListOfN 0 + , testListOfN 1 + , testListOfN 2 + , testListOfN 5000 + ] + + +testListOfN : Int -> Test +testListOfN n = + let + xs = + List.range 1 n + + xsOpp = + List.range -n -1 + + xsNeg = + foldl (::) [] xsOpp + + -- assume foldl and (::) work + zs = + List.range 0 n + + sumSeq k = + k * (k + 1) // 2 + + xsSum = + sumSeq n + + mid = + n // 2 + in + describe (toString n ++ " elements") + [ describe "foldl" + [ test "order" <| \() -> Expect.equal (n) (foldl (\x acc -> x) 0 xs) + , test "total" <| \() -> Expect.equal (xsSum) (foldl (+) 0 xs) + ] + , describe "foldr" + [ test "order" <| \() -> Expect.equal (min 1 n) (foldr (\x acc -> x) 0 xs) + , test "total" <| \() -> Expect.equal (xsSum) (foldl (+) 0 xs) + ] + , describe "map" + [ test "identity" <| \() -> Expect.equal (xs) (map identity xs) + , test "linear" <| \() -> Expect.equal (List.range 2 (n + 1)) (map ((+) 1) xs) + ] + , test "isEmpty" <| \() -> Expect.equal (n == 0) (isEmpty xs) + , test "length" <| \() -> Expect.equal (n) (length xs) + , test "reverse" <| \() -> Expect.equal (xsOpp) (reverse xsNeg) + , describe "member" + [ test "positive" <| \() -> Expect.equal (True) (member n zs) + , test "negative" <| \() -> Expect.equal (False) (member (n + 1) xs) + ] + , test "head" <| + \() -> + if n == 0 then + Expect.equal (Nothing) (head xs) + else + Expect.equal (Just 1) (head xs) + , describe "List.filter" + [ test "none" <| \() -> Expect.equal ([]) (List.filter (\x -> x > n) xs) + , test "one" <| \() -> Expect.equal ([ n ]) (List.filter (\z -> z == n) zs) + , test "all" <| \() -> Expect.equal (xs) (List.filter (\x -> x <= n) xs) + ] + , describe "take" + [ test "none" <| \() -> Expect.equal ([]) (take 0 xs) + , test "some" <| \() -> Expect.equal (List.range 0 (n - 1)) (take n zs) + , test "all" <| \() -> Expect.equal (xs) (take n xs) + , test "all+" <| \() -> Expect.equal (xs) (take (n + 1) xs) + ] + , describe "drop" + [ test "none" <| \() -> Expect.equal (xs) (drop 0 xs) + , test "some" <| \() -> Expect.equal ([ n ]) (drop n zs) + , test "all" <| \() -> Expect.equal ([]) (drop n xs) + , test "all+" <| \() -> Expect.equal ([]) (drop (n + 1) xs) + ] + , test "repeat" <| \() -> Expect.equal (map (\x -> -1) xs) (repeat n -1) + , test "append" <| \() -> Expect.equal (xsSum * 2) (append xs xs |> foldl (+) 0) + , test "(::)" <| \() -> Expect.equal (append [ -1 ] xs) (-1 :: xs) + , test "List.concat" <| \() -> Expect.equal (append xs (append zs xs)) (List.concat [ xs, zs, xs ]) + , test "intersperse" <| + \() -> + Expect.equal + ( min -(n - 1) 0, xsSum ) + (intersperse -1 xs |> foldl (\x ( c1, c2 ) -> ( c2, c1 + x )) ( 0, 0 )) + , describe "partition" + [ test "left" <| \() -> Expect.equal ( xs, [] ) (partition (\x -> x > 0) xs) + , test "right" <| \() -> Expect.equal ( [], xs ) (partition (\x -> x < 0) xs) + , test "split" <| \() -> Expect.equal ( List.range (mid + 1) n, List.range 1 mid ) (partition (\x -> x > mid) xs) + ] + , describe "map2" + [ test "same length" <| \() -> Expect.equal (map ((*) 2) xs) (map2 (+) xs xs) + , test "long first" <| \() -> Expect.equal (map (\x -> x * 2 - 1) xs) (map2 (+) zs xs) + , test "short first" <| \() -> Expect.equal (map (\x -> x * 2 - 1) xs) (map2 (+) xs zs) + ] + , test "unzip" <| \() -> Expect.equal ( xsNeg, xs ) (map (\x -> ( -x, x )) xs |> unzip) + , describe "filterMap" + [ test "none" <| \() -> Expect.equal ([]) (filterMap (\x -> Nothing) xs) + , test "all" <| \() -> Expect.equal (xsNeg) (filterMap (\x -> Just -x) xs) + , let + halve x = + if x % 2 == 0 then + Just (x // 2) + else + Nothing + in + test "some" <| \() -> Expect.equal (List.range 1 mid) (filterMap halve xs) + ] + , describe "concatMap" + [ test "none" <| \() -> Expect.equal ([]) (concatMap (\x -> []) xs) + , test "all" <| \() -> Expect.equal (xsNeg) (concatMap (\x -> [ -x ]) xs) + ] + , test "indexedMap" <| \() -> Expect.equal (map2 (,) zs xsNeg) (indexedMap (\i x -> ( i, -x )) xs) + , test "sum" <| \() -> Expect.equal (xsSum) (sum xs) + , test "product" <| \() -> Expect.equal (0) (product zs) + , test "maximum" <| + \() -> + if n == 0 then + Expect.equal (Nothing) (maximum xs) + else + Expect.equal (Just n) (maximum xs) + , test "minimum" <| + \() -> + if n == 0 then + Expect.equal (Nothing) (minimum xs) + else + Expect.equal (Just 1) (minimum xs) + , describe "all" + [ test "false" <| \() -> Expect.equal (False) (all (\z -> z < n) zs) + , test "true" <| \() -> Expect.equal (True) (all (\x -> x <= n) xs) + ] + , describe "any" + [ test "false" <| \() -> Expect.equal (False) (any (\x -> x > n) xs) + , test "true" <| \() -> Expect.equal (True) (any (\z -> z >= n) zs) + ] + , describe "sort" + [ test "sorted" <| \() -> Expect.equal (xs) (sort xs) + , test "unsorted" <| \() -> Expect.equal (xsOpp) (sort xsNeg) + ] + , describe "sortBy" + [ test "sorted" <| \() -> Expect.equal (xsNeg) (sortBy negate xsNeg) + , test "unsorted" <| \() -> Expect.equal (xsNeg) (sortBy negate xsOpp) + ] + , describe "sortWith" + [ test "sorted" <| \() -> Expect.equal (xsNeg) (sortWith (flip compare) xsNeg) + , test "unsorted" <| \() -> Expect.equal (xsNeg) (sortWith (flip compare) xsOpp) + ] + , test "scanl" <| \() -> Expect.equal (0 :: map sumSeq xs) (scanl (+) 0 xs) + ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Maybe.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Maybe.elm new file mode 100644 index 0000000..dfa8e5e --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Maybe.elm @@ -0,0 +1,169 @@ +module Test.Maybe exposing (tests) + +import Basics exposing (..) +import Maybe exposing (..) +import Test exposing (..) +import Expect + +tests : Test +tests = + describe "Maybe Tests" + + [ describe "Common Helpers Tests" + + [ describe "withDefault Tests" + [ test "no default used" <| + \() -> Expect.equal 0 (Maybe.withDefault 5 (Just 0)) + , test "default used" <| + \() -> Expect.equal 5 (Maybe.withDefault 5 (Nothing)) + ] + + , describe "map Tests" + ( let f = (\n -> n + 1) in + [ test "on Just" <| + \() -> + Expect.equal + (Just 1) + (Maybe.map f (Just 0)) + , test "on Nothing" <| + \() -> + Expect.equal + Nothing + (Maybe.map f Nothing) + ] + ) + + , describe "map2 Tests" + ( let f = (+) in + [ test "on (Just, Just)" <| + \() -> + Expect.equal + (Just 1) + (Maybe.map2 f (Just 0) (Just 1)) + , test "on (Just, Nothing)" <| + \() -> + Expect.equal + Nothing + (Maybe.map2 f (Just 0) Nothing) + , test "on (Nothing, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map2 f Nothing (Just 0)) + ] + ) + + , describe "map3 Tests" + ( let f = (\a b c -> a + b + c) in + [ test "on (Just, Just, Just)" <| + \() -> + Expect.equal + (Just 3) + (Maybe.map3 f (Just 1) (Just 1) (Just 1)) + , test "on (Just, Just, Nothing)" <| + \() -> + Expect.equal + Nothing + (Maybe.map3 f (Just 1) (Just 1) Nothing) + , test "on (Just, Nothing, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map3 f (Just 1) Nothing (Just 1)) + , test "on (Nothing, Just, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map3 f Nothing (Just 1) (Just 1)) + ] + ) + + , describe "map4 Tests" + ( let f = (\a b c d -> a + b + c + d) in + [ test "on (Just, Just, Just, Just)" <| + \() -> + Expect.equal + (Just 4) + (Maybe.map4 f (Just 1) (Just 1) (Just 1) (Just 1)) + , test "on (Just, Just, Just, Nothing)" <| + \() -> + Expect.equal + Nothing + (Maybe.map4 f (Just 1) (Just 1) (Just 1) Nothing) + , test "on (Just, Just, Nothing, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map4 f (Just 1) (Just 1) Nothing (Just 1)) + , test "on (Just, Nothing, Just, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map4 f (Just 1) Nothing (Just 1) (Just 1)) + , test "on (Nothing, Just, Just, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map4 f Nothing (Just 1) (Just 1) (Just 1)) + ] + ) + + , describe "map5 Tests" + ( let f = (\a b c d e -> a + b + c + d + e) in + [ test "on (Just, Just, Just, Just, Just)" <| + \() -> + Expect.equal + (Just 5) + (Maybe.map5 f (Just 1) (Just 1) (Just 1) (Just 1) (Just 1)) + , test "on (Just, Just, Just, Just, Nothing)" <| + \() -> + Expect.equal + Nothing + (Maybe.map5 f (Just 1) (Just 1) (Just 1) (Just 1) Nothing) + , test "on (Just, Just, Just, Nothing, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map5 f (Just 1) (Just 1) (Just 1) Nothing (Just 1)) + , test "on (Just, Just, Nothing, Just, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map5 f (Just 1) (Just 1) Nothing (Just 1) (Just 1)) + , test "on (Just, Nothing, Just, Just, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map5 f (Just 1) Nothing (Just 1) (Just 1) (Just 1)) + , test "on (Nothing, Just, Just, Just, Just)" <| + \() -> + Expect.equal + Nothing + (Maybe.map5 f Nothing (Just 1) (Just 1) (Just 1) (Just 1)) + ] + ) + + ] + + , describe "Chaining Maybes Tests" + + [ describe "andThen Tests" + [ test "succeeding chain" <| + \() -> + Expect.equal + (Just 1) + (Maybe.andThen (\a -> Just a) (Just 1)) + , test "failing chain (original Maybe failed)" <| + \() -> + Expect.equal + Nothing + (Maybe.andThen (\a -> Just a) Nothing) + , test "failing chain (chained function failed)" <| + \() -> + Expect.equal + Nothing + (Maybe.andThen (\a -> Nothing) (Just 1)) + ] + ] + + ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Regex.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Regex.elm new file mode 100644 index 0000000..478d44b --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Regex.elm @@ -0,0 +1,57 @@ +module Test.Regex exposing (tests) + +import Basics exposing (..) +import Regex exposing (..) +import Test exposing (..) +import Expect + + +tests : Test +tests = + let + simpleTests = + describe "Simple Stuff" + [ test "split All" <| \() -> Expect.equal [ "a", "b" ] (split All (regex ",") "a,b") + , test "split" <| \() -> Expect.equal [ "a", "b,c" ] (split (AtMost 1) (regex ",") "a,b,c") + , test "split idempotent" <| + \() -> + let + findComma = + regex "," + in + Expect.equal + (split (AtMost 1) findComma "a,b,c,d,e") + (split (AtMost 1) findComma "a,b,c,d,e") + , test "find All" <| + \() -> + Expect.equal + ([ Match "a" [] 0 1, Match "b" [] 1 2 ]) + (find All (regex ".") "ab") + , test "find All" <| + \() -> + Expect.equal + ([ Match "" [] 0 1 ]) + (find All (regex ".*") "") + , test "replace AtMost 0" <| + \() -> + Expect.equal "The quick brown fox" + (replace (AtMost 0) (regex "[aeiou]") (\_ -> "") "The quick brown fox") + , test "replace AtMost 1" <| + \() -> + Expect.equal "Th quick brown fox" + (replace (AtMost 1) (regex "[aeiou]") (\_ -> "") "The quick brown fox") + , test "replace AtMost 2" <| + \() -> + Expect.equal "Th qick brown fox" + (replace (AtMost 2) (regex "[aeiou]") (\_ -> "") "The quick brown fox") + , test "replace All" <| + \() -> + Expect.equal "Th qck brwn fx" + (replace All (regex "[aeiou]") (\_ -> "") "The quick brown fox") + , test "replace using index" <| + \() -> + Expect.equal "a1b3c" + (replace All (regex ",") (\match -> toString match.index) "a,b,c") + ] + in + describe "Regex" [ simpleTests ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Result.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Result.elm new file mode 100644 index 0000000..6679e7e --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Result.elm @@ -0,0 +1,70 @@ +module Test.Result exposing (tests) + +import Basics exposing (..) +import Result +import Result exposing (Result(..)) +import String +import Test exposing (..) +import Expect + + +isEven n = + if n % 2 == 0 then + Ok n + else + Err "number is odd" + + +add3 a b c = + a + b + c + + +add4 a b c d = + a + b + c + d + + +add5 a b c d e = + a + b + c + d + e + + +tests : Test +tests = + let + mapTests = + describe "map Tests" + [ test "map Ok" <| \() -> Expect.equal (Ok 3) (Result.map ((+) 1) (Ok 2)) + , test "map Err" <| \() -> Expect.equal (Err "error") (Result.map ((+) 1) (Err "error")) + ] + + mapNTests = + describe "mapN Tests" + [ test "map2 Ok" <| \() -> Expect.equal (Ok 3) (Result.map2 (+) (Ok 1) (Ok 2)) + , test "map2 Err" <| \() -> Expect.equal (Err "x") (Result.map2 (+) (Ok 1) (Err "x")) + , test "map3 Ok" <| \() -> Expect.equal (Ok 6) (Result.map3 add3 (Ok 1) (Ok 2) (Ok 3)) + , test "map3 Err" <| \() -> Expect.equal (Err "x") (Result.map3 add3 (Ok 1) (Ok 2) (Err "x")) + , test "map4 Ok" <| \() -> Expect.equal (Ok 10) (Result.map4 add4 (Ok 1) (Ok 2) (Ok 3) (Ok 4)) + , test "map4 Err" <| \() -> Expect.equal (Err "x") (Result.map4 add4 (Ok 1) (Ok 2) (Ok 3) (Err "x")) + , test "map5 Ok" <| \() -> Expect.equal (Ok 15) (Result.map5 add5 (Ok 1) (Ok 2) (Ok 3) (Ok 4) (Ok 5)) + , test "map5 Err" <| \() -> Expect.equal (Err "x") (Result.map5 add5 (Ok 1) (Ok 2) (Ok 3) (Ok 4) (Err "x")) + ] + + andThenTests = + describe "andThen Tests" + [ test "andThen Ok" <| \() -> Expect.equal (Ok 42) ((String.toInt "42") |> Result.andThen isEven) + , test "andThen first Err" <| + \() -> + Expect.equal + (Err "could not convert string '4.2' to an Int") + (String.toInt "4.2" |> Result.andThen isEven) + , test "andThen second Err" <| + \() -> + Expect.equal + (Err "number is odd") + (String.toInt "41" |> Result.andThen isEven) + ] + in + describe "Result Tests" + [ mapTests + , mapNTests + , andThenTests + ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Set.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Set.elm new file mode 100644 index 0000000..e98caaa --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/Set.elm @@ -0,0 +1,52 @@ +module Test.Set exposing (tests) + +import Basics exposing (..) +import Set +import Set exposing (Set) +import List +import Test exposing (..) +import Expect + + +set : Set Int +set = + Set.fromList <| List.range 1 100 + + +setPart1 : Set Int +setPart1 = + Set.fromList <| List.range 1 50 + + +setPart2 : Set Int +setPart2 = + Set.fromList <| List.range 51 100 + + +pred : Int -> Bool +pred x = + x <= 50 + + +tests : Test +tests = + let + queryTests = + describe "query Tests" + [ test "size of set of 100 elements" <| + \() -> Expect.equal 100 (Set.size set) + ] + + filterTests = + describe "filter Tests" + [ test "Simple filter" <| + \() -> Expect.equal setPart1 <| Set.filter pred set + ] + + partitionTests = + describe "partition Tests" + [ test "Simple partition" <| + \() -> Expect.equal ( setPart1, setPart2 ) <| Set.partition pred set + ] + in + describe "Set Tests" [ queryTests, partitionTests, filterTests ] diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/String.elm b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/String.elm new file mode 100644 index 0000000..f682775 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/Test/String.elm @@ -0,0 +1,110 @@ +module Test.String exposing (tests) + +import Basics exposing (..) +import List +import Maybe exposing (..) +import Result exposing (Result(..)) +import String +import Test exposing (..) +import Expect + + +tests : Test +tests = + let + simpleTests = + describe "Simple Stuff" + [ test "is empty" <| \() -> Expect.equal True (String.isEmpty "") + , test "is not empty" <| \() -> Expect.equal True (not (String.isEmpty ("the world"))) + , test "length" <| \() -> Expect.equal 11 (String.length "innumerable") + , test "endsWith" <| \() -> Expect.equal True <| String.endsWith "ship" "spaceship" + , test "reverse" <| \() -> Expect.equal "desserts" (String.reverse "stressed") + , test "repeat" <| \() -> Expect.equal "hahaha" (String.repeat 3 "ha") + , test "indexes" <| \() -> Expect.equal [ 0, 2 ] (String.indexes "a" "aha") + , test "empty indexes" <| \() -> Expect.equal [] (String.indexes "" "aha") + ] + + combiningTests = + describe "Combining Strings" + [ test "uncons non-empty" <| \() -> Expect.equal (Just ( 'a', "bc" )) (String.uncons "abc") + , test "uncons empty" <| \() -> Expect.equal Nothing (String.uncons "") + , test "append 1" <| \() -> Expect.equal "butterfly" (String.append "butter" "fly") + , test "append 2" <| \() -> Expect.equal "butter" (String.append "butter" "") + , test "append 3" <| \() -> Expect.equal "butter" (String.append "" "butter") + , test "concat" <| \() -> Expect.equal "nevertheless" (String.concat [ "never", "the", "less" ]) + , test "split commas" <| \() -> Expect.equal [ "cat", "dog", "cow" ] (String.split "," "cat,dog,cow") + , test "split slashes" <| \() -> Expect.equal [ "home", "steve", "Desktop", "" ] (String.split "/" "home/steve/Desktop/") + , test "join spaces" <| \() -> Expect.equal "cat dog cow" (String.join " " [ "cat", "dog", "cow" ]) + , test "join slashes" <| \() -> Expect.equal "home/steve/Desktop" (String.join "/" [ "home", "steve", "Desktop" ]) + , test "slice 1" <| \() -> Expect.equal "c" (String.slice 2 3 "abcd") + , test "slice 2" <| \() -> Expect.equal "abc" (String.slice 0 3 "abcd") + , test "slice 3" <| \() -> Expect.equal "abc" (String.slice 0 -1 "abcd") + , test "slice 4" <| \() -> Expect.equal "cd" (String.slice -2 4 "abcd") + ] + + intTests = + describe "String.toInt" + [ goodInt "1234" 1234 + , goodInt "+1234" 1234 + , goodInt "-1234" -1234 + , badInt "1.34" + , badInt "1e31" + , badInt "123a" + , goodInt "0123" 123 + , goodInt "0x001A" 26 + , goodInt "0x001a" 26 + , goodInt "0xBEEF" 48879 + , badInt "0x12.0" + , badInt "0x12an" + ] + + floatTests = + describe "String.toFloat" + [ goodFloat "123" 123 + , goodFloat "3.14" 3.14 + , goodFloat "+3.14" 3.14 + , goodFloat "-3.14" -3.14 + , goodFloat "0.12" 0.12 + , goodFloat ".12" 0.12 + , goodFloat "1e-42" 1e-42 + , goodFloat "6.022e23" 6.022e23 + , goodFloat "6.022E23" 6.022e23 + , goodFloat "6.022e+23" 6.022e23 + , badFloat "6.022e" + , badFloat "6.022n" + , badFloat "6.022.31" + ] + in + describe "String" [ simpleTests, combiningTests, intTests, floatTests ] + + + +-- NUMBER HELPERS + + +goodInt : String -> Int -> Test +goodInt str int = + test str <| \_ -> + Expect.equal (Ok int) (String.toInt str) + + +badInt : String -> Test +badInt str = + test str <| \_ -> + Expect.equal + (Err ("could not convert string '" ++ str ++ "' to an Int")) + (String.toInt str) + + +goodFloat : String -> Float -> Test +goodFloat str float = + test str <| \_ -> + Expect.equal (Ok float) (String.toFloat str) + + +badFloat : String -> Test +badFloat str = + test str <| \_ -> + Expect.equal + (Err ("could not convert string '" ++ str ++ "' to a Float")) + (String.toFloat str) diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/elm-package.json b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/elm-package.json new file mode 100644 index 0000000..e27cfa4 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/elm-package.json @@ -0,0 +1,17 @@ +{ + "version": "1.1.1", + "summary": "Tests for Elm's standard libraries", + "repository": "http://github.com/elm-lang/core.git", + "license": "BSD3", + "source-directories": [ + ".", + "../src" + ], + "exposed-modules": [ ], + "native-modules": true, + "dependencies": { + "elm-community/elm-test": "3.1.0 <= v < 4.0.0", + "rtfeldman/node-test-runner": "3.0.0 <= v < 4.0.0" + }, + "elm-version": "0.18.0 <= v < 0.19.0" +} diff --git a/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/run-tests.sh b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/run-tests.sh new file mode 100755 index 0000000..9e2f9bc --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/core/5.1.1/tests/run-tests.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +cd "$(dirname "$0")" +set -e + + +elm-package install -y + +VERSION_DIR="$(ls elm-stuff/packages/elm-lang/core/)" +CORE_PACKAGE_DIR="elm-stuff/packages/elm-lang/core/$VERSION_DIR" +CORE_GIT_DIR="$(dirname $PWD)" + +echo "Linking $CORE_PACKAGE_DIR to $CORE_GIT_DIR" +rm -rf $CORE_PACKAGE_DIR +ln -s $CORE_GIT_DIR $CORE_PACKAGE_DIR + +elm-make --yes --output test.js Main.elm + +elm-test Main.elm diff --git a/client/elm-stuff/packages/elm-lang/dom/1.1.1/.gitignore b/client/elm-stuff/packages/elm-lang/dom/1.1.1/.gitignore new file mode 100644 index 0000000..e185314 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/dom/1.1.1/.gitignore @@ -0,0 +1 @@ +elm-stuff \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/dom/1.1.1/LICENSE b/client/elm-stuff/packages/elm-lang/dom/1.1.1/LICENSE new file mode 100644 index 0000000..24bdd38 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/dom/1.1.1/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2016, Evan Czaplicki + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of Evan Czaplicki nor the names of other + 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 +OWNER 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. \ No newline at end of file diff --git a/client/elm-stuff/packages/elm-lang/dom/1.1.1/README.md b/client/elm-stuff/packages/elm-lang/dom/1.1.1/README.md new file mode 100644 index 0000000..7d542d8 --- /dev/null +++ b/client/elm-stuff/packages/elm-lang/dom/1.1.1/README.md @@ -0,0 +1,7 @@ +# Mess with the DOM + +Sometimes you want to manually set the **focus** to a particular input field. + +Other times you want to be able to control how things **scroll**. + +This library makes it possible to do these kinds of operations as tasks. diff --git a/client/elm-stuff/packages/elm-lang/dom/1.1.1/assets/boundaries.acorn b/client/elm-stuff/packages/elm-lang/dom/1.1.1/assets/boundaries.acorn new file mode 100644 index 0000000000000000000000000000000000000000..e7b58a008f6f12c9032fcf2364a29c80632dd4fa GIT binary patch literal 188416 zcmeFabzD?m+c&zV7`i)$?(PtV?oJ7%1{k^}L_`?=reyyy4+bN)Do{rSx7y;tnD_IF?V+UtsSEo(~?Y&Ztx6%-oa7LJkyC;))~ zGztX(ASV2n2*1BKBEkXu?-Rlv^7px>M`+-`rT_aOF%W+tOhHJ2adrT%axNai?qoYb z-~@pa1Wph*LEr>|69i5WI6>e9ffEEy5I8~L1c4I-P7pXj-~@pa1Wph*LEr>|69i5W zI6>e9ffEEy5I8~L4+Q*SNG5S{NIY4%o4Y^8-z^#wde$vGJQV955snG_&vUr8m9D0Z zF3Ltz%S0FTpSdU@6xI_Jj)@8vLj}48VE#Icbn}nEpxpg~+=Zi{NG28*NWAfXwf1Kl zVX*)8%3&y>e_bxvEffuWS`6%o}ZdZB^>+v`uc<`PtryQX?k= zYG=(Iw~MB{Gwj3}?_$tU(0z4mG#H%cWCI*ajja$J3td10)dG;c^BI6SX&Vh04R#0Q z`Sk#TbF>7CE^novnDRzI0psa~yotgB{*~*&(CvEzU2h_7jqRoby35!0H>G-;z*#0Q ziW_yz5Pt_#9JHz`2O=_Q1(2G3IiOWc06<2oQ-OCaP(BlggVpcu&m1El($tWc=N>rr zX+^uu{m)ea7r7p8Wrx30y!kBwC1{KpN$kRLwS3_^FMrzXc@x zN~1>|*-opUA4rzH`Z+{nWbs4S(%-ov_l3|007aou<3%3#&T@=gQajB#N=u%^J(?zW zk!Ot7q>z6sbt@}3MQ3zhU_7tsrf6NV)FWL1nHXK6@zB8`>B)Q%265v{_p7szos-z-1an)zkTxib+a&=SH)(BKgg4r^jaSP;yz2QoK!7WExPu0Bq(Wo}17o!2(v%T)}4Q+fz+%*eD0{UWd3475aVSTV&SR7C+4=QuyPTX@w)SOWGCy?0)H($8003_wyWJZ!WY&D zxJsng%z)TvjsfqPh#w4y$NU^MnrqQULL{$ou-1K+FJ#>6=K0+gwD520%fPCjo*4v` zdCdSzdR-}CkjEDcJXxqNd7Uomg|PExpchdTUX74#1Q48iMGal??*>9P!W%H*f=7TX zslN&ysLYYAzeUSJpJm9OZ@5icYSVmLyjXukb8!8E!?0{kL*5{B;V(B4tqP9do&tB1iV9XXt6Q27B@1Nw1LT@|WjMU77I-cRVFf zYD{cF_H22T_<_3uz%iod3apGT z0Z40P*>n>HtdGp^F1#%g>A(Ms9Hb%FsqYJ6H>Dc_I7%WM z5%mLW0LzWk#=#BnDmbvgP7V-|8hZfO%rF_L384i@)UrEZ^jbL&sQBMA0}lOL>v;T3 zD=7IOgpU{ma*PlI^UM4`z=J(G7?_cG%5`B1P!IvkG(bTiI3)49D?rTNa|iI;0!sj) z=Ap#FEs|9M5zFAu3`9jFS-fir2&WWK0)8A`8^GeS6IdW?P_m z1I)>&tP# zWQRmUa~s?6iWJ7ZuuEGn0d+yrt`>7bC?JE@xI&a|d;lU|6ZOY;kK5r=Fl_4RBOW#K z@&H1ur3xr*5U#+Pkq)R(ibdZe5HFs35S9Zy=&1%sE8ZDc?#n&AxG_l;$l>7vB#*a( zfetk#P|eEd1@#gJK;`M9z4CeBV9yRni`rJHFLIUU)U?{ zB}=Dv!oIRc(bLr~ypH(BQMnX!`^md=-`R!n<5&eYK_gcpr;4k@Zp8)53g4JPyjwjt z(rqjUn9!!8zc~UR%r|3_9|1_kpZnx%k^Nl-)MEMCg z;LSnQMy*Ulco;ItqB&M3BtotmY-AhYF-yA1U74x&rf*ua9XD0278?5EMv{cO{Jv;RDht66GVZCWkt6@}^;)Yl=M6>{$Q-Z)AVJAOq=j5}e*P5{7;&nt{H%_&XGQP3I8$x~QQC_k!# zzf-H)L}OesHS0)3jp^d<2049341_qJ<1v+4@7A4*a5;xrJEu&SS)pP!H+XbB-Tnin zS@mx2_!pX*o>&_3&XAFZas#LvYNk|wisgn^WoZD&vI+};WEfH{&@kBBEgY;;3MWCO zfGLS53Q*)hHo$qVtBEf>6l4TL@k812&R!%R5 z&Z+=*@7zZKq0?KKIVf*?+TM;>i4+2GkRJI)z4*s|I5-XdJ25y81k{ip$zhz{wwJh; zKQI*XtlW8-*iyBMg7`Z*>b0*##$EMWi`>nsUq2VO6Z`Dkp;=d%-yO!jQ_tA=KP8^+ zP=M&*eltV{XfA5K+mGc#JA0GQpKL)dwRXH&-v(zv3J=b>LXpEAFDjak0RV%<5mnCz z03wfNpqwH{Hn?i+Foy7~(=92lUgmZ#;QP~J{%zKFJo(e;|fCxC#;~;8uI%q(Vuz|)w^yG#zOfz%46!kvG z(QM+wvT_$ybrAmU3A^GtRR@%bima+BBypKR=k4{QX?Q$s(oJ*6^$fmn^LZBJ=jGWM z8%C}1)(w{B=S7+ue$f=d(ATQc`dS%9TZ&+8ZWQKq+3Opcif$LQ7v(KF8ApdmSex7` zw)%9|_)EN$7yUp9Uf_($>0B8vn~BnV1#g|xS+_N3O1;|E{Y;~8DR|AVxxkoZhaxNF z?D^&{w}*zAMbD~u+q_l|iwTxn8SL5NdsCUe7;7H=UfsavE%tCI#9a9!+J^yFRls;= zdaNJ48UU*16;dp|a_e{|5m(X+H&~4G>-j9O)fPmO&gzwF6jLzQ&KKod#aJ5I+oG`H zmx8T~Y)!C*vJD0EZyygA8W;VLYMB3Y#rkW!g&~I$R&FoIdOXR>*Vg!2A!&`o*Nkpo zUDNA%g!fXvPDB6syeST`_uJ?B`sj}vg?8;0td)1Krv+V)sO&bRM!~N*bh2^>14M9) zNQT1(r(vTQk%hyreg|#So zIj90`gOCIw*SA91Zo8AZqb+Pzz%2FoWgs#OhxBUEUDC9n9a}DDMFBx0-wq@p&YkiZqN>#!scZG5K$kPoLuHUQ&` z)_`FMr))3y$+Z;v?#$Xi)I0H=`-;tYXSmsUP!%EdUWO-= z`YRXjNA{E)UqD3M%?=0y0!XfdD4hVKp%~!MRN);C1~3q!mrVVX+=RKUyT$;$mBWMJ zX6|6wr4GuhewHNF3fKoyqj3R$%qpBxuqJNWtde=DynY@m0O82rVsNK z--6TYZq#37)Cz_&h*9U7xRT-^^cKX+pY*s=^=Zjf0NIE6XIki1Im87WTViWUBOLgm zPPJ^tlY}F7XN}?;Q!vZlCegDh*w(o=7P@UyF&&O6$el0tB1v{Hd1+YWRm#aXB@Ym& z7n&+&*0Ttt7PS%(A?J1g49|jrHk}qfyJb4!7V%9jO;=AcKzb;2nlMmfOi_I_@IsFv zvA+%|o6$`n7>O)yU1aP}GC|wsq+S+Es~OhJV@Q^da$|>~Kn*_y+@?p=-jl}P=~|j^ z`PGJ4#^GCU(gnub9*>=w)UCgJimrHH)NZkJKiz9JxS=@rD$_&`7?I49qqkrZAqYCu z{q8tGHJB40#IJ(_<`m3ATC|$*Y8!rl4COm@B_Xzl0@fRIrnF&io?e!+uL|Uez;CP` z1Iapiynv1rphr9-?E#d}T0xrNp!Z^&vKed)f#_?M0+etNA}f+v1w;1xeO@AK-M^32 znmICM($n+b=Xew@7i(=a_mM*1YW~UVNIzL}?E=7&OuLtkEP4J#7f|FIyaB}V%L4%9 z2>Xg;819ZpK03UExL-L(Sb1N1LV zM|E~Z$xGeIi$+Wj{okdZMlmD7P8cb))wmhz$alvE+S^0o);q83)3%++G7tvW%FVe&zuoulHx1^rCMv>ATp093#xv6HbF^uvQU8=0 z78+q;G*R$reO{y8IKjs2ADH>RUui^WhlBUpNX9;`T!+#UN9~&n*&m?jQDG!EpU84H z1?4F@p)cHZ{#m&nv<$|C1^M}|A#y25b>&!C`0EH?w+{&xCSwC_aR`4v_eF)%ULyTa$WDUMrRr@PAag6XPyk zn$aboGjsXS-GAy@x1zwCVr5fxU-9Us&Sa@A^7feUN7t5A1^tte=wQ>1Yjs_Mw2S5G zc420ho@fZZ`FZ6CvNuh#HM>)@R5@XHUR;>)i4CBvKGI5Ux{g%aff-ek86}B*WzlKe z=d3+S$f*z!*7Rwg#AYj{nk!EmTnmt>Kk6^ZePuA)D6@b<{f{!Z#rwye`*eS5^fU=N zfRTS`^!|4;_#YZQW)37>c#JIbqqGLgs$j=VQctJqz0<>g$>8oG4)=b`;P~}68qqE@{+J2vmfIzfFy;S}!RLJ=tnU?F z5pA5rhQ;`QY6<9G|CbD|9dXy_!c~vDmA%M&oWEu8W?T#!Fxh|~Z}el(oL8M%f8gWQ z(8!(Q>YbyQIICtZ(e%~?>=zZYvn~6dzh7_{IE)?y!fEbRfD75Ts`67~29AKDd-3c9 zaoKX6ARqWx0XC_Lj}!wrucJOa$c{DJ>c<$Myqk=6W=yqR?`V6(>&L2&N6FQUM?CE9y!fD(pV z1vEOgthDg_T)Z1I3Otg{z(H2Lt5HAd0QI0WEg;sSP6lj5ea!^^2T=ngFQRGysa9ct z@RQb@H^l@YAyrzC?Rl)%Gzx&=}}lCu%;j4yNAx+ z0LXM4(cYb49AYKX1;DR~7y<~f77c(aQ#LXub0-7xL{vXeL-V`4Vs@It0d<`)5g>7Q zC;=3SuIqrM0b6SK^7ezUik;g(6RUUcsOQ)B;o$6qJ{Aa*0pyt>oGTh~qa6p&<+(V*m1<+D)iu}MT?pkP7RW^c>uC@cA+Xp9f%bfTYzvCmgc36R|seZ z;CTp;1J9qdJqf<;BC)Vj$Mf<0L*iD#W6~A^5h@kE5T6b!5V5l(+Y0gTasVO=zKxm( z#}@!C2|NcJL@5Jm13naVJMA3OtJa3|B~NJC=)L| z_?$&cPzm0vERiE6dG&sX=jl847|jpg;(l>mS$g;7$B%}Me630(_o)Bxhf#t@ShxZo zR-!6Ei?1dI!TlS6i~>L{3ixr598VS;q{@dC2Wj+!vCR?&t4K%{kj>aM0Mg{zD8QEd zo|Umy7&_V}E+fY7%{u&k@*HQi