From 3e0aa4a57e0b7eb6c8a617daa33607fc89278683 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 18 Sep 2024 13:28:19 -0400 Subject: [PATCH 01/13] chore(DotcomWeb): use verified routes --- lib/dotcom_web.ex | 18 ++++++++++++++++-- test/support/conn_case.ex | 5 ++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/dotcom_web.ex b/lib/dotcom_web.ex index 17fa464b39..a8820fec32 100644 --- a/lib/dotcom_web.ex +++ b/lib/dotcom_web.ex @@ -16,6 +16,8 @@ defmodule DotcomWeb do below. """ + def static_paths, do: ~w(assets fonts images favicon robots.txt) + def model do quote do # Define common model functionality @@ -73,7 +75,8 @@ defmodule DotcomWeb do project_path: 2, project_path: 3, project_update_path: 3, - project_update_path: 4 + project_update_path: 4, + static_url: 2 ] import DotcomWeb.CmsRouterHelpers @@ -149,7 +152,18 @@ defmodule DotcomWeb do alias DotcomWeb.Router.Helpers import DotcomWeb.Components - import DotcomWeb.CoreComponents + + # Routes generation with the ~p sigil + unquote(verified_routes()) + end + end + + def verified_routes do + quote do + use Phoenix.VerifiedRoutes, + endpoint: DotcomWeb.Endpoint, + router: DotcomWeb.Router, + statics: DotcomWeb.static_paths() end end diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 6ae64db03d..8af07af1ce 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -39,7 +39,8 @@ defmodule DotcomWeb.ConnCase do project_path: 2, project_path: 3, project_update_path: 3, - project_update_path: 4 + project_update_path: 4, + static_path: 2 ] import DotcomWeb.CmsRouterHelpers @@ -48,6 +49,8 @@ defmodule DotcomWeb.ConnCase do # The default endpoint for testing @endpoint DotcomWeb.Endpoint + use DotcomWeb, :verified_routes + import DotcomWeb.ConnCase, only: [default_conn: 0] end end From ef14c5bc8bcc37cc1c0c2970f822a68c1dcddf31 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Mon, 9 Sep 2024 15:30:04 -0400 Subject: [PATCH 02/13] deps(mix): install mbta_metro --- mix.exs | 10 ++-------- mix.lock | 11 ++++++++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/mix.exs b/mix.exs index a7f82f8731..6dbcb6d276 100644 --- a/mix.exs +++ b/mix.exs @@ -6,7 +6,7 @@ defmodule DotCom.Mixfile do # app and version expected by `mix compile.app` app: :dotcom, version: "0.0.1", - elixir: "~> 1.12", + elixir: "~> 1.17", elixirc_paths: elixirc_paths(Mix.env()), compilers: Mix.compilers(), # configures `mix compile` to embed all code and priv content in the _build directory instead of using symlinks @@ -93,19 +93,13 @@ defmodule DotCom.Mixfile do {:gettext, "0.25.0"}, {:hackney, "1.20.1"}, {:hammer, "6.2.1"}, - {:heroicons, - github: "tailwindlabs/heroicons", - tag: "v2.1.5", - sparse: "optimized", - app: false, - compile: false, - depth: 1}, {:html_sanitize_ex, "1.4.3"}, {:httpoison, "2.2.1"}, {:inflex, "2.1.0"}, {:jason, "1.4.4", override: true}, {:logster, "1.1.1"}, {:mail, "0.3.1"}, + {:mbta_metro, ">= 0.0.0", runtime: false}, {:mock, "0.3.8", [only: :test]}, {:mox, "1.1.0", [only: :test]}, {:nebulex, "2.6.3"}, diff --git a/mix.lock b/mix.lock index 80c3048802..7b67d1c961 100644 --- a/mix.lock +++ b/mix.lock @@ -4,6 +4,7 @@ "aws": {:hex, :aws, "1.0.2", "39e0844ff126662e031e4bf186a6631b3402bf39f6af639260b27a4c29fdfe1a", [:mix], [{:aws_signature, "~> 0.3", [hex: :aws_signature, repo: "hexpm", optional: false]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "0e5cb8dee3f50a81cd93820f4c68407371c3ebbf860000a92a51ecb7920e808d"}, "aws_credentials": {:hex, :aws_credentials, "0.3.2", "ba2ccee4ec6dcb5426cf71830b7afd73795b1f19655f401d4401015b468fec6f", [:rebar3], [{:eini, "~> 2.2.4", [hex: :eini_beam, repo: "hexpm", optional: false]}, {:iso8601, "~> 1.3.4", [hex: :iso8601, repo: "hexpm", optional: false]}, {:jsx, "~> 3.1.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "2e748626a935a7a544647fb79d7054f38db8bf378978542c962ccbeab387387b"}, "aws_signature": {:hex, :aws_signature, "0.3.2", "adf33bc4af00b2089b7708bf20e3246f09c639a905a619b3689f0a0a22c3ef8f", [:rebar3], [], "hexpm", "b0daf61feb4250a8ab0adea60db3e336af732ff71dd3fb22e45ae3dcbd071e44"}, + "bandit": {:hex, :bandit, "1.5.7", "6856b1e1df4f2b0cb3df1377eab7891bec2da6a7fd69dc78594ad3e152363a50", [:mix], [{:hpax, "~> 1.0.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "f2dd92ae87d2cbea2fa9aa1652db157b6cba6c405cb44d4f6dd87abba41371cd"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"}, "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, @@ -18,6 +19,7 @@ "decorator": {:hex, :decorator, "1.4.0", "a57ac32c823ea7e4e67f5af56412d12b33274661bb7640ec7fc882f8d23ac419", [:mix], [], "hexpm", "0a07cedd9083da875c7418dea95b78361197cf2bf3211d743f6f7ce39656597f"}, "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, "diskusage_logger": {:hex, :diskusage_logger, "0.2.0", "04fc48b538fe4de43153542a71ea94f623d54707d85844123baacfceedf625c3", [:mix], [], "hexpm", "e3f2aed1b0fc4590931c089a6453a4c4eb4c945912aa97bcabcc0cff7851f34d"}, + "earmark": {:hex, :earmark, "1.4.47", "7e7596b84fe4ebeb8751e14cbaeaf4d7a0237708f2ce43630cfd9065551f94ca", [:mix], [], "hexpm", "3e96bebea2c2d95f3b346a7ff22285bc68a99fbabdad9b655aa9c6be06c698f8"}, "earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"}, "ecto": {:hex, :ecto, "3.12.1", "626765f7066589de6fa09e0876a253ff60c3d00870dd3a1cd696e2ba67bfceea", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df0045ab9d87be947228e05a8d153f3e06e0d05ab10c3b3cc557d2f7243d1940"}, "eflame": {:hex, :eflame, "1.0.1", "0664d287e39eef3c413749254b3af5f4f8b00be71c1af67d325331c4890be0fc", [:mix], [], "hexpm", "e0b08854a66f9013129de0b008488f3411ae9b69b902187837f994d7a99cf04e"}, @@ -25,6 +27,7 @@ "eini": {:hex, :eini_beam, "2.2.4", "02143b1dce4dda4243248e7d9b3d8274b8d9f5a666445e3d868e2cce79e4ff22", [:rebar3], [], "hexpm", "12de479d144b19e09bb92ba202a7ea716739929afdf9dff01ad802e2b1508471"}, "elixir_make": {:hex, :elixir_make, "0.8.4", "4960a03ce79081dee8fe119d80ad372c4e7badb84c493cc75983f9d3bc8bde0f", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.0", [hex: :certifi, repo: "hexpm", optional: true]}], "hexpm", "6e7f1d619b5f61dfabd0a20aa268e575572b542ac31723293a4c1a567d5ef040"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, + "esbuild": {:hex, :esbuild, "0.8.1", "0cbf919f0eccb136d2eeef0df49c4acf55336de864e63594adcea3814f3edf41", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "25fc876a67c13cb0a776e7b5d7974851556baeda2085296c14ab48555ea7560f"}, "ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"}, "ex_machina": {:hex, :ex_machina, "2.8.0", "a0e847b5712065055ec3255840e2c78ef9366634d62390839d4880483be38abe", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "79fe1a9c64c0c1c1fab6c4fa5d871682cb90de5885320c187d117004627a7729"}, "ex_unit_summary": {:hex, :ex_unit_summary, "0.1.0", "7b0352afc5e6a933c805df0a539b66b392ac12ba74d8b208db7d83f77cb57049", [:mix], [], "hexpm", "8c87d0deade3657102902251d2ec60b5b94560004ce0e2c2fa5b466232716bd6"}, @@ -38,7 +41,7 @@ "gettext": {:hex, :gettext, "0.25.0", "98a95a862a94e2d55d24520dd79256a15c87ea75b49673a2e2f206e6ebc42e5d", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "38e5d754e66af37980a94fb93bb20dcde1d2361f664b0a19f01e87296634051f"}, "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"}, "hammer": {:hex, :hammer, "6.2.1", "5ae9c33e3dceaeb42de0db46bf505bd9c35f259c8defb03390cd7556fea67ee2", [:mix], [{:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm", "b9476d0c13883d2dc0cc72e786bac6ac28911fba7cc2e04b70ce6a6d9c4b2bdc"}, - "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "ad0ad1f6d51bd64dcd67e363d2b2833a8de25154", [tag: "v2.1.5", sparse: "optimized", depth: 1]}, + "heroicons": {:hex, :heroicons, "0.5.6", "95d730e7179c633df32d95c1fdaaecdf81b0da11010b89b737b843ac176a7eb5", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:phoenix_live_view, ">= 0.18.2", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "ca267f02a5fa695a4178a737b649fb6644a2e399639d4ba7964c18e8a58c2352"}, "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.3", "67b3d9fa8691b727317e0cc96b9b3093be00ee45419ffb221cdeee88e75d1360", [:mix], [{:mochiweb, "~> 2.15 or ~> 3.1", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "87748d3c4afe949c7c6eb7150c958c2bcba43fc5b2a02686af30e636b74bccb7"}, "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, @@ -51,8 +54,11 @@ "logster": {:hex, :logster, "1.1.1", "d6fddac540dd46adde0c894024500867fe63b0043713f842c62da5815e21db10", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "d18e852c430812ad1c9756998ebe46ec814c724e6eb551a512d7e3f8dee24cef"}, "mail": {:hex, :mail, "0.3.1", "cb0a14e4ed8904e4e5a08214e686ccf6f9099346885db17d8c309381f865cc5c", [:mix], [], "hexpm", "1db701e89865c1d5fa296b2b57b1cd587587cca8d8a1a22892b35ef5a8e352a6"}, "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, + "makeup_eex": {:hex, :makeup_eex, "0.1.2", "93a5ef3d28ed753215dba2d59cb40408b37cccb4a8205e53ef9b5319a992b700", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.16 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_html, "~> 0.1.0 or ~> 1.0", [hex: :makeup_html, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "6140eafb28215ad7182282fd21d9aa6dcffbfbe0eb876283bc6b768a6c57b0c3"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, "makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, + "makeup_html": {:hex, :makeup_html, "0.1.1", "c3d4abd39d5f7e925faca72ada6e9cc5c6f5fa7cd5bc0158315832656cf14d7f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "44f2a61bc5243645dd7fafeaa6cc28793cd22f3c76b861e066168f9a5b2c26a4"}, + "mbta_metro": {:hex, :mbta_metro, "0.0.1", "8148e2feeb32c1f361daf43f210361beb07bf432c5caa03ff08d931e68e4fef4", [:mix], [{:heroicons, "0.5.6", [hex: :heroicons, repo: "hexpm", optional: false]}, {:phoenix, "1.7.14", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, "1.0.0-rc.6", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_storybook, "0.6.4", [hex: :phoenix_storybook, repo: "hexpm", optional: false]}], "hexpm", "8fcc05f5a5eadb052233c5ac8a10929f3df8c5b264791505156c82c4b1403fc2"}, "meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, @@ -79,6 +85,7 @@ "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.5.3", "f2161c207fda0e4fb55165f650f7f8db23f02b29e3bff00ff7ef161d6ac1f09d", [:mix], [{:file_system, "~> 0.3 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "b4ec9cd73cb01ff1bd1cac92e045d13e7030330b74164297d1aee3907b54803c"}, "phoenix_live_view": {:hex, :phoenix_live_view, "1.0.0-rc.6", "47d2669995ea326e5c71f5c1bc9177109cebf211385c638faa7b5862a401e516", [:mix], [{:floki, "~> 0.36", [hex: :floki, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e56e4f1642a0b20edc2488cab30e5439595e0d8b5b259f76ef98b1c4e2e5b527"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, + "phoenix_storybook": {:hex, :phoenix_storybook, "0.6.4", "d7bfdf6a20214251ff7453cbcb9de5f6f8a7db606f9c21846a87ba09058d8f0e", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:heroicons, "~> 0.5", [hex: :heroicons, repo: "hexpm", optional: true]}, {:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: true]}, {:makeup_eex, "~> 0.1.0", [hex: :makeup_eex, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html_helpers, "~> 1.0", [hex: :phoenix_html_helpers, repo: "hexpm", optional: false]}, {:phoenix_live_view, "> 0.18.7", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}], "hexpm", "a63669c010e638882d287aae9c2cfd4a2c64d68e05f85403e213101283a74d3f"}, "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, "phoenix_view": {:hex, :phoenix_view, "2.0.4", "b45c9d9cf15b3a1af5fb555c674b525391b6a1fe975f040fb4d913397b31abf4", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "4e992022ce14f31fe57335db27a28154afcc94e9983266835bb3040243eb620b"}, "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, @@ -103,12 +110,14 @@ "slipstream": {:hex, :slipstream, "1.1.1", "7e56f62f1a9ee81351e3c36f57b9b187e00dc2f470e70ba46ea7ad16e80b061f", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mint_web_socket, "~> 0.2 or ~> 1.0", [hex: :mint_web_socket, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.1 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c20e420cde1654329d38ec3aa1c0e4debbd4c91ca421491e7984ad4644e638a6"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "sweet_xml": {:hex, :sweet_xml, "0.7.4", "a8b7e1ce7ecd775c7e8a65d501bc2cd933bff3a9c41ab763f5105688ef485d08", [:mix], [], "hexpm", "e7c4b0bdbf460c928234951def54fe87edf1a170f6896675443279e2dbeba167"}, + "tailwind": {:hex, :tailwind, "0.2.3", "277f08145d407de49650d0a4685dc062174bdd1ae7731c5f1da86163a24dfcdb", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "8e45e7a34a676a7747d04f7913a96c770c85e6be810a1d7f91e713d3a3655b5d"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "telemetry_metrics": {:hex, :telemetry_metrics, "1.0.0", "29f5f84991ca98b8eb02fc208b2e6de7c95f8bb2294ef244a176675adc7775df", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f23713b3847286a534e005126d4c959ebcca68ae9582118ce436b521d1d47d5d"}, "telemetry_metrics_splunk": {:hex, :telemetry_metrics_splunk, "0.0.6-alpha", "76812c1ece239955d1d9c7a0556fd51ccaebb89abcec357b9c9dd67e619057b4", [:mix], [{:finch, "~> 0.18", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.1", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:recase, "~> 0.8", [hex: :recase, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "2150e2112b846cf68bf604b871386d68114fc289472d9a4308146ad7b3fbeee6"}, "telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"}, "telemetry_test": {:hex, :telemetry_test, "0.1.2", "122d927567c563cf57773105fa8104ae4299718ec2cbdddcf6776562c7488072", [:mix], [{:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7bd41a49ecfd33ecd82d2c7edae19a5736f0d2150206d0ee290dcf3885d0e14d"}, "tesla": {:hex, :tesla, "1.11.2", "24707ac48b52f72f88fc05d242b1c59a85d1ee6f16f19c312d7d3419665c9cd5", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, ">= 1.0.0", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "c549cd03aec6a7196a641689dd378b799e635eb393f689b4bd756f750c7a4014"}, + "thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"}, "timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"}, "typed_ecto_schema": {:hex, :typed_ecto_schema, "0.4.1", "a373ca6f693f4de84cde474a67467a9cb9051a8a7f3f615f1e23dc74b75237fa", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm", "85c6962f79d35bf543dd5659c6adc340fd2480cacc6f25d2cc2933ea6e8fcb3b"}, "typed_struct": {:hex, :typed_struct, "0.2.1", "e1993414c371f09ff25231393b6430bd89d780e2a499ae3b2d2b00852f593d97", [:mix], [], "hexpm", "8f5218c35ec38262f627b2c522542f1eae41f625f92649c0af701a6fab2e11b3"}, From d86cec394f9a4872942c358f4dfd4f8e9b88f84b Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Tue, 17 Sep 2024 15:44:53 -0400 Subject: [PATCH 03/13] deps(npm): install mbta_metro --- assets/package-lock.json | 679 ++++++++++++++++++++++++++++++--------- assets/package.json | 1 + 2 files changed, 526 insertions(+), 154 deletions(-) diff --git a/assets/package-lock.json b/assets/package-lock.json index aeb5e7b879..561ed0fc3a 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -35,6 +35,7 @@ "leaflet": "^1.4.0", "leaflet-rotatedmarker": "^0.2.0", "lodash": "^4.17.21", + "mbta_metro": "^0.0.13", "mobile-detect": "^1.4.5", "phoenix": "file:../deps/phoenix", "phoenix_html": "file:../deps/phoenix_html", @@ -163,7 +164,7 @@ "license": "MIT" }, "../deps/phoenix_html": { - "version": "3.3.3" + "version": "4.1.0" }, "node_modules/@adobe/css-tools": { "version": "4.3.3", @@ -360,7 +361,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -2804,7 +2804,7 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -2815,7 +2815,7 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -4071,7 +4071,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -4088,7 +4087,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, "engines": { "node": ">=12" }, @@ -4100,7 +4098,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "engines": { "node": ">=12" }, @@ -4111,14 +4108,12 @@ "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -4135,7 +4130,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -4150,7 +4144,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -4818,7 +4811,6 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -4828,7 +4820,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -4859,14 +4850,12 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -4878,9 +4867,95 @@ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "dev": true }, + "node_modules/@mapbox/geojson-rewind": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", + "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", + "dependencies": { + "get-stream": "^6.0.1", + "minimist": "^1.2.6" + }, + "bin": { + "geojson-rewind": "geojson-rewind" + } + }, + "node_modules/@mapbox/geojson-rewind/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@mapbox/jsonlint-lines-primitives": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==" + }, + "node_modules/@mapbox/tiny-sdf": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz", + "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==" + }, + "node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==" + }, + "node_modules/@mapbox/vector-tile": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "dependencies": { + "@mapbox/point-geometry": "~0.1.0" + } + }, + "node_modules/@mapbox/whoots-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", + "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.3.1.tgz", + "integrity": "sha512-5ueL4UDitzVtceQ8J4kY+Px3WK+eZTsmGwha3MBKHKqiHvKrjWWwBCIl1K8BuJSc5OFh83uI8IFNoFvQxX2uUw==", + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^4.0.0", + "minimist": "^1.2.8", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "sort-object": "^3.0.3", + "tinyqueue": "^3.0.0" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -4892,7 +4967,6 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -4900,7 +4974,6 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -4914,7 +4987,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" @@ -4926,6 +4998,15 @@ "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", "dev": true }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@remix-run/router": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.9.0.tgz", @@ -5165,16 +5246,14 @@ } }, "node_modules/@tailwindcss/forms": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", - "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==", - "dev": true, - "license": "MIT", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz", + "integrity": "sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==", "dependencies": { "mini-svg-data-uri": "^1.2.3" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20" } }, "node_modules/@testing-library/dom": { @@ -5417,22 +5496,22 @@ }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.3", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/aria-query": { @@ -5623,9 +5702,17 @@ } }, "node_modules/@types/geojson": { - "version": "7946.0.10", - "dev": true, - "license": "MIT" + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + }, + "node_modules/@types/geojson-vt": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz", + "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==", + "dependencies": { + "@types/geojson": "*" + } }, "node_modules/@types/googlemaps": { "version": "3.43.3", @@ -5715,6 +5802,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mapbox__point-geometry": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", + "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==" + }, + "node_modules/@types/mapbox__vector-tile": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", + "dependencies": { + "@types/geojson": "*", + "@types/mapbox__point-geometry": "*", + "@types/pbf": "*" + } + }, "node_modules/@types/mdast": { "version": "3.0.12", "dev": true, @@ -5735,7 +5837,7 @@ }, "node_modules/@types/node": { "version": "18.11.9", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/node-forge": { @@ -5757,6 +5859,11 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/pbf": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==" + }, "node_modules/@types/phoenix": { "version": "1.5.4", "dev": true, @@ -5909,6 +6016,14 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/testing-library__jest-dom": { "version": "5.14.5", "dev": true, @@ -6487,7 +6602,7 @@ }, "node_modules/acorn": { "version": "8.10.0", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -6732,7 +6847,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6753,12 +6867,10 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.2", - "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -6789,7 +6901,7 @@ }, "node_modules/arg": { "version": "4.1.3", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/argparse": { @@ -6808,6 +6920,14 @@ "deep-equal": "^2.0.5" } }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/array-equal": { "version": "1.0.0", "dev": true, @@ -6942,6 +7062,14 @@ "node": "*" } }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ast-types-flow": { "version": "0.0.7", "dev": true, @@ -7464,7 +7592,6 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -7509,7 +7636,6 @@ }, "node_modules/binary-extensions": { "version": "2.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -7610,7 +7736,6 @@ }, "node_modules/braces": { "version": "3.0.2", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.0.1" @@ -7748,6 +7873,23 @@ "node": ">= 0.8" } }, + "node_modules/bytewise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", + "integrity": "sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==", + "dependencies": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "node_modules/bytewise-core": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", + "integrity": "sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==", + "dependencies": { + "typewise-core": "^1.2" + } + }, "node_modules/cachedir": { "version": "2.3.0", "dev": true, @@ -7788,7 +7930,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -7955,7 +8096,6 @@ }, "node_modules/chokidar": { "version": "3.5.3", - "dev": true, "funding": [ { "type": "individual", @@ -8372,12 +8512,11 @@ }, "node_modules/create-require": { "version": "1.1.1", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.3", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -8783,7 +8922,6 @@ }, "node_modules/cssesc": { "version": "3.0.0", - "dev": true, "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -9129,14 +9267,6 @@ "node": ">=8" } }, - "node_modules/cypress/node_modules/minimist": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/cypress/node_modules/ms": { "version": "2.1.2", "dev": true, @@ -9500,7 +9630,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, "license": "Apache-2.0" }, "node_modules/diff": { @@ -9539,7 +9668,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, "license": "MIT" }, "node_modules/dns-packet": { @@ -9657,11 +9785,15 @@ "dev": true, "license": "MIT" }, + "node_modules/earcut": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", + "integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/ecc-jsbn": { "version": "0.1.2", @@ -9697,7 +9829,6 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, "license": "MIT" }, "node_modules/emojis-list": { @@ -10973,6 +11104,17 @@ "dev": true, "license": "MIT" }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "dev": true, @@ -11035,7 +11177,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -11067,7 +11208,6 @@ }, "node_modules/fastq": { "version": "1.13.0", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -11167,7 +11307,6 @@ }, "node_modules/fill-range": { "version": "7.0.1", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -11306,7 +11445,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -11322,7 +11460,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "engines": { "node": ">=14" }, @@ -11430,7 +11567,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -11444,7 +11580,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11488,6 +11623,11 @@ "node": ">=6.9.0" } }, + "node_modules/geojson-vt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", + "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==" + }, "node_modules/get-caller-file": { "version": "2.0.5", "dev": true, @@ -11557,6 +11697,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/getos": { "version": "3.2.1", "dev": true, @@ -11578,6 +11726,11 @@ "assert-plus": "^1.0.0" } }, + "node_modules/gl-matrix": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", + "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" + }, "node_modules/glob": { "version": "7.2.3", "dev": true, @@ -11599,7 +11752,6 @@ }, "node_modules/glob-parent": { "version": "5.1.2", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -11862,7 +12014,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -12227,7 +12378,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "dev": true, "funding": [ { "type": "github", @@ -12491,7 +12641,6 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -12563,7 +12712,6 @@ "version": "2.15.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -12613,9 +12761,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-extglob": { "version": "2.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12623,7 +12778,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12639,7 +12793,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -12723,7 +12876,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -12761,7 +12913,6 @@ }, "node_modules/is-plain-object": { "version": "2.0.4", - "dev": true, "license": "MIT", "dependencies": { "isobject": "^3.0.1" @@ -12947,12 +13098,10 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14924,7 +15073,6 @@ "version": "1.21.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "dev": true, "bin": { "jiti": "bin/jiti.js" } @@ -15083,6 +15231,11 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stringify-pretty-compact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==" + }, "node_modules/json-stringify-safe": { "version": "5.0.1", "dev": true, @@ -15142,9 +15295,13 @@ "dev": true, "license": "MIT" }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" + }, "node_modules/kind-of": { "version": "6.0.3", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -15231,14 +15388,12 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, "engines": { "node": ">=10" } }, "node_modules/lines-and-columns": { "version": "1.2.4", - "dev": true, "license": "MIT" }, "node_modules/lint-staged": { @@ -16044,7 +16199,7 @@ }, "node_modules/make-error": { "version": "1.3.6", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/makeerror": { @@ -16070,6 +16225,89 @@ "version": "0.1.0", "dev": true }, + "node_modules/maplibre-gl": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.7.0.tgz", + "integrity": "sha512-hkt7je7NxiMQE8EpCxLWP8t6tkK6SkrMe0hIBjYd4Ar/Q7BOCILxthGmGnU993Mwmkvs2mGiXnVUSOK12DeCzg==", + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^2.0.6", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "@maplibre/maplibre-gl-style-spec": "^20.3.1", + "@types/geojson": "^7946.0.14", + "@types/geojson-vt": "3.2.5", + "@types/mapbox__point-geometry": "^0.1.4", + "@types/mapbox__vector-tile": "^1.3.4", + "@types/pbf": "^3.0.5", + "@types/supercluster": "^7.1.3", + "earcut": "^3.0.0", + "geojson-vt": "^4.0.2", + "gl-matrix": "^3.4.3", + "global-prefix": "^4.0.0", + "kdbush": "^4.0.2", + "murmurhash-js": "^1.0.0", + "pbf": "^3.3.0", + "potpack": "^2.0.0", + "quickselect": "^3.0.0", + "supercluster": "^8.0.1", + "tinyqueue": "^3.0.0", + "vt-pbf": "^3.1.3" + }, + "engines": { + "node": ">=16.14.0", + "npm": ">=8.1.0" + }, + "funding": { + "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" + } + }, + "node_modules/maplibre-gl/node_modules/global-prefix": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", + "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", + "dependencies": { + "ini": "^4.1.3", + "kind-of": "^6.0.3", + "which": "^4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/maplibre-gl/node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/maplibre-gl/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "engines": { + "node": ">=16" + } + }, + "node_modules/maplibre-gl/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, "node_modules/mathml-tag-names": { "version": "2.1.3", "dev": true, @@ -16079,6 +16317,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/mbta_metro": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/mbta_metro/-/mbta_metro-0.0.13.tgz", + "integrity": "sha512-42WA4/HO1+c6baSQrljm4WpZF9fG20sNTaRUPmToG65Xu7/4ONaNi0Y1O0izFiQisCowgpPeji5xUEC2/6zR4Q==", + "dependencies": { + "@tailwindcss/forms": "^0.5.9", + "maplibre-gl": "^4.7.0", + "preline": "^2.4.1" + } + }, "node_modules/mdast-util-from-markdown": { "version": "0.8.5", "dev": true, @@ -16214,7 +16462,6 @@ }, "node_modules/merge2": { "version": "1.4.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -16270,7 +16517,6 @@ }, "node_modules/micromatch": { "version": "4.0.5", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.2", @@ -16356,7 +16602,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", - "dev": true, "license": "MIT", "bin": { "mini-svg-data-uri": "cli.js" @@ -16379,9 +16624,9 @@ } }, "node_modules/minimist": { - "version": "1.2.7", - "dev": true, - "license": "MIT", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -16411,7 +16656,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -16948,11 +17192,15 @@ "multicast-dns": "cli.js" } }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, "license": "MIT", "dependencies": { "any-promise": "^1.0.0", @@ -16964,7 +17212,6 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -17117,7 +17364,6 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -17187,7 +17433,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -17458,7 +17703,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { @@ -17555,7 +17799,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17563,14 +17806,12 @@ }, "node_modules/path-parse": { "version": "1.0.7", - "dev": true, "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -17587,7 +17828,6 @@ "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "dev": true, "engines": { "node": "14 || >=16.14" } @@ -17624,6 +17864,18 @@ "through": "~2.3" } }, + "node_modules/pbf": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz", + "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==", + "dependencies": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/pend": { "version": "1.2.0", "dev": true, @@ -17651,12 +17903,10 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -17686,7 +17936,6 @@ }, "node_modules/pirates": { "version": "4.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -17769,7 +18018,6 @@ "version": "8.4.41", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -18370,7 +18618,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", @@ -18388,7 +18635,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" @@ -18469,7 +18715,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -18505,7 +18750,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true, "license": "MIT", "engines": { "node": ">=14" @@ -18518,7 +18762,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", - "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -18821,7 +19064,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -19375,7 +19617,6 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -19459,9 +19700,13 @@ }, "node_modules/postcss-value-parser": { "version": "4.2.0", - "dev": true, "license": "MIT" }, + "node_modules/potpack": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz", + "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==" + }, "node_modules/preact": { "version": "10.18.1", "resolved": "https://registry.npmjs.org/preact/-/preact-10.18.1.tgz", @@ -19471,6 +19716,14 @@ "url": "https://opencollective.com/preact" } }, + "node_modules/preline": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/preline/-/preline-2.4.1.tgz", + "integrity": "sha512-30yx5s2gEOTBWXSTPa+Th23/kGryn9Inhmp9KPzz9G8DZPp9j/LkGyyrSvdsuXh4Clc/sJFLObumFrbI/WmB0w==", + "dependencies": { + "@popperjs/core": "^2.11.2" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "dev": true, @@ -19592,6 +19845,11 @@ "reflect.ownkeys": "^0.2.0" } }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" + }, "node_modules/proxy-addr": { "version": "2.0.7", "dev": true, @@ -19761,7 +20019,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "dev": true, "funding": [ { "type": "github", @@ -19786,6 +20043,11 @@ "node": ">=8" } }, + "node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==" + }, "node_modules/raf": { "version": "3.4.1", "dev": true, @@ -19985,7 +20247,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, "license": "MIT", "dependencies": { "pify": "^2.3.0" @@ -19995,7 +20256,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -20122,7 +20382,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" @@ -20460,7 +20719,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -20493,6 +20751,14 @@ "node": ">=8" } }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, "node_modules/resolve.exports": { "version": "1.1.0", "dev": true, @@ -20532,7 +20798,6 @@ }, "node_modules/reusify": { "version": "1.0.4", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -20581,7 +20846,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "dev": true, "funding": [ { "type": "github", @@ -20601,6 +20865,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -20947,6 +21216,20 @@ "node": ">= 0.8.0" } }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "dev": true, @@ -20965,7 +21248,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -20976,7 +21258,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -21125,6 +21406,38 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sort-asc": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.2.0.tgz", + "integrity": "sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-desc": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.2.0.tgz", + "integrity": "sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-object": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-3.0.3.tgz", + "integrity": "sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==", + "dependencies": { + "bytewise": "^1.1.0", + "get-value": "^2.0.2", + "is-extendable": "^0.1.1", + "sort-asc": "^0.2.0", + "sort-desc": "^0.2.0", + "union-value": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "dev": true, @@ -21137,7 +21450,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -21268,6 +21580,40 @@ "node": "*" } }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "dev": true, @@ -21472,7 +21818,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -21488,7 +21833,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -21560,7 +21904,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -21574,7 +21917,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -21936,7 +22278,6 @@ "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", @@ -21959,7 +22300,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -21974,7 +22314,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -21984,7 +22323,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -21994,7 +22332,6 @@ "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -22015,7 +22352,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -22031,7 +22367,6 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -22072,6 +22407,14 @@ "url": "https://opencollective.com/postcss/" } }, + "node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "dependencies": { + "kdbush": "^4.0.2" + } + }, "node_modules/supports-color": { "version": "5.5.0", "dev": true, @@ -22116,7 +22459,6 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -22299,7 +22641,6 @@ "version": "3.4.10", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==", - "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -22337,14 +22678,12 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, "license": "MIT" }, "node_modules/tailwindcss/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -22486,7 +22825,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, "license": "MIT", "dependencies": { "any-promise": "^1.0.0" @@ -22496,7 +22834,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" @@ -22525,6 +22862,11 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==" + }, "node_modules/tmp": { "version": "0.2.1", "dev": true, @@ -22551,7 +22893,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -22621,7 +22962,6 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, "license": "Apache-2.0" }, "node_modules/ts-jest": { @@ -22789,7 +23129,7 @@ }, "node_modules/ts-node": { "version": "10.9.1", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -22831,7 +23171,7 @@ }, "node_modules/ts-node/node_modules/acorn-walk": { "version": "8.2.0", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -22839,7 +23179,7 @@ }, "node_modules/ts-node/node_modules/diff": { "version": "4.0.2", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -22954,7 +23294,7 @@ }, "node_modules/typescript": { "version": "4.8.4", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -22964,6 +23304,19 @@ "node": ">=4.2.0" } }, + "node_modules/typewise": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", + "integrity": "sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==", + "dependencies": { + "typewise-core": "^1.2.0" + } + }, + "node_modules/typewise-core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", + "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "dev": true, @@ -23043,6 +23396,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/unist-util-find-all-after": { "version": "3.0.2", "dev": true, @@ -23173,7 +23540,6 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/utils-merge": { @@ -23199,7 +23565,7 @@ }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -23281,6 +23647,16 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vt-pbf": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", + "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", + "dependencies": { + "@mapbox/point-geometry": "0.1.0", + "@mapbox/vector-tile": "^1.3.1", + "pbf": "^3.2.1" + } + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "dev": true, @@ -23921,7 +24297,6 @@ }, "node_modules/which": { "version": "2.0.2", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -24021,7 +24396,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -24038,7 +24412,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -24053,7 +24426,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -24064,8 +24436,7 @@ "node_modules/wrap-ansi-cjs/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", @@ -24227,7 +24598,7 @@ }, "node_modules/yn": { "version": "3.1.1", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" diff --git a/assets/package.json b/assets/package.json index 1e4c5bb2ea..71e08ada0b 100644 --- a/assets/package.json +++ b/assets/package.json @@ -30,6 +30,7 @@ "leaflet": "^1.4.0", "leaflet-rotatedmarker": "^0.2.0", "lodash": "^4.17.21", + "mbta_metro": "^0.0.13", "mobile-detect": "^1.4.5", "phoenix": "file:../deps/phoenix", "phoenix_html": "file:../deps/phoenix_html", From 22014091e22706a8b9502a0158d3b3a6535b416b Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Mon, 9 Sep 2024 15:30:57 -0400 Subject: [PATCH 04/13] configure Tailwind for MbtaMetro compatibility --- assets/css/app.scss | 1 + assets/tailwind.config.js | 134 +++++++++++++++++--------------------- 2 files changed, 61 insertions(+), 74 deletions(-) diff --git a/assets/css/app.scss b/assets/css/app.scss index 2c34ff1cd7..af92a59df7 100644 --- a/assets/css/app.scss +++ b/assets/css/app.scss @@ -1,4 +1,5 @@ // TailwindCSS +@import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities'; diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js index 780d75c345..bcb54f7a2a 100644 --- a/assets/tailwind.config.js +++ b/assets/tailwind.config.js @@ -1,80 +1,66 @@ // See the Tailwind configuration guide for advanced usage // https://tailwindcss.com/docs/configuration -const plugin = require("tailwindcss/plugin") -const fs = require("fs") -const path = require("path") +const { + colors, + content, + fontFamily, + plugins, + safelist +} = require("mbta_metro"); +const plugin = require("tailwindcss/plugin"); module.exports = { - prefix: "tw-", - corePlugins: { - preflight: false + important: true, + corePlugins: { + preflight: false + }, + blocklist: ["container", "collapse"], + content: [ + ...content, + "./js/**/*.js", + "./ts/**/*.ts", + "./ts/**/*.tsx", + "../lib/dotcom_web.ex", + "../lib/dotcom_web/**/*.*ex", + "../deps/mbta_metro/lib/mbta_metro/**/*.ex" + ], + theme: { + extend: { + colors: { + ...colors + } }, - content: [ - "./js/**/*.js", - "./ts/**/*.ts", - "./ts/**/*.tsx", - "../lib/dotcom_web.ex", - "../lib/dotcom_web/**/*.*ex" - ], - theme: { - extend: { - colors: { - brand: "#FD4F00", - } - }, - }, - plugins: [ - require("@tailwindcss/forms"), - // Allows prefixing tailwind classes with LiveView classes to add rules - // only when LiveView classes are applied, for example: - // - //
- // - plugin(({ addVariant }) => addVariant("phx-click-loading", [".phx-click-loading&", ".phx-click-loading &"])), - plugin(({ addVariant }) => addVariant("phx-submit-loading", [".phx-submit-loading&", ".phx-submit-loading &"])), - plugin(({ addVariant }) => addVariant("phx-change-loading", [".phx-change-loading&", ".phx-change-loading &"])), - - // Embeds Heroicons (https://heroicons.com) into your app.css bundle - // See your `CoreComponents.icon/1` for more information. - // - plugin(function ({ matchComponents, theme }) { - let iconsDir = path.join(__dirname, "../deps/heroicons/optimized") - let values = {} - let icons = [ - ["", "/24/outline"], - ["-solid", "/24/solid"], - ["-mini", "/20/solid"], - ["-micro", "/16/solid"] - ] - icons.forEach(([suffix, dir]) => { - fs.readdirSync(path.join(iconsDir, dir)).forEach(file => { - let name = path.basename(file, ".svg") + suffix - values[name] = { name, fullPath: path.join(iconsDir, dir, file) } - }) - }) - matchComponents({ - "hero": ({ name, fullPath }) => { - let content = fs.readFileSync(fullPath).toString().replace(/\r?\n|\r/g, "") - let size = theme("spacing.6") - if (name.endsWith("-mini")) { - size = theme("spacing.5") - } else if (name.endsWith("-micro")) { - size = theme("spacing.4") - } - return { - [`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`, - "-webkit-mask": `var(--hero-${name})`, - "mask": `var(--hero-${name})`, - "mask-repeat": "no-repeat", - "background-color": "currentColor", - "vertical-align": "middle", - "display": "inline-block", - "width": size, - "height": size - } - } - }, { values }) - }) - ], -} + fontFamily: { + ...fontFamily + } + }, + safelist: [...safelist], + plugins: [ + ...plugins, + require("@tailwindcss/forms"), + // Allows prefixing tailwind classes with LiveView classes to add rules + // only when LiveView classes are applied, for example: + // + //
+ // + plugin(({ addVariant }) => + addVariant("phx-click-loading", [ + ".phx-click-loading&", + ".phx-click-loading &" + ]) + ), + plugin(({ addVariant }) => + addVariant("phx-submit-loading", [ + ".phx-submit-loading&", + ".phx-submit-loading &" + ]) + ), + plugin(({ addVariant }) => + addVariant("phx-change-loading", [ + ".phx-change-loading&", + ".phx-change-loading &" + ]) + ) + ] +}; From 1e167dc112367c48cdf19fade84fb5eb08de54e3 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Mon, 9 Sep 2024 15:31:45 -0400 Subject: [PATCH 05/13] remove CoreComponents since they're in mbta_metro --- lib/dotcom_web.ex | 2 + lib/dotcom_web/components/core_components.ex | 697 ------------------- 2 files changed, 2 insertions(+), 697 deletions(-) delete mode 100644 lib/dotcom_web/components/core_components.ex diff --git a/lib/dotcom_web.ex b/lib/dotcom_web.ex index a8820fec32..1799ff0691 100644 --- a/lib/dotcom_web.ex +++ b/lib/dotcom_web.ex @@ -139,6 +139,8 @@ defmodule DotcomWeb do import Phoenix.HTML import PhoenixHTMLHelpers.Form use PhoenixHTMLHelpers + # Use all MBTA Metro components + use MbtaMetro # Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc) import Phoenix.LiveView.Helpers diff --git a/lib/dotcom_web/components/core_components.ex b/lib/dotcom_web/components/core_components.ex deleted file mode 100644 index a29865121f..0000000000 --- a/lib/dotcom_web/components/core_components.ex +++ /dev/null @@ -1,697 +0,0 @@ -defmodule DotcomWeb.CoreComponents do - @moduledoc """ - Provides core UI components. - - At first glance, this module may seem daunting, but its goal is to provide - core building blocks for your application, such as modals, tables, and - forms. The components consist mostly of markup and are well-documented - with doc strings and declarative assigns. You may customize and style - them in any way you want, based on your application growth and needs. - - The default components use Tailwind CSS, a utility-first CSS framework. - See the [Tailwind CSS documentation](https://tailwindcss.com) to learn - how to customize them or feel free to swap in another framework altogether. - - Icons are provided by [heroicons](https://heroicons.com). See `icon/1` for usage. - """ - use Phoenix.Component - - alias Phoenix.LiveView.JS - import DotcomWeb.Gettext - - @doc """ - Renders a modal. - - ## Examples - - <.modal id="confirm-modal"> - This is a modal. - - - JS commands may be passed to the `:on_cancel` to configure - the closing/cancel event, for example: - - <.modal id="confirm" on_cancel={JS.navigate(~p"/posts")}> - This is another modal. - - - """ - attr :id, :string, required: true - attr :show, :boolean, default: false - attr :on_cancel, JS, default: %JS{} - slot :inner_block, required: true - - def modal(assigns) do - ~H""" -
- - """ - end - - @doc """ - Renders flash notices. - - ## Examples - - <.flash kind={:info} flash={@flash} /> - <.flash kind={:info} phx-mounted={show("#flash")}>Welcome Back! - """ - attr :id, :string, doc: "the optional id of flash container" - attr :flash, :map, default: %{}, doc: "the map of flash messages to display" - attr :title, :string, default: nil - attr :kind, :atom, values: [:info, :error], doc: "used for styling and flash lookup" - attr :rest, :global, doc: "the arbitrary HTML attributes to add to the flash container" - - slot :inner_block, doc: "the optional inner block that renders the flash message" - - def flash(assigns) do - assigns = assign_new(assigns, :id, fn -> "flash-#{assigns.kind}" end) - - ~H""" -
hide("##{@id}")} - role="alert" - class={[ - "tw-fixed tw-top-2 tw-right-2 tw-mr-2 tw-w-80 tw-sm:w-96 tw-z-50 tw-rounded-lg tw-p-3 tw-ring-1", - @kind == :info && "tw-bg-emerald-50 tw-text-emerald-800 tw-ring-emerald-500 tw-fill-cyan-900", - @kind == :error && - "tw-bg-rose-50 tw-text-rose-900 tw-shadow-md tw-ring-rose-500 tw-fill-rose-900" - ]} - {@rest} - > -

- <.icon :if={@kind == :info} name="hero-information-circle-mini" class="tw-h-4 tw-w-4" /> - <.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="tw-h-4 tw-w-4" /> - <%= @title %> -

-

<%= msg %>

- -
- """ - end - - @doc """ - Shows the flash group with standard titles and content. - - ## Examples - - <.flash_group flash={@flash} /> - """ - attr :flash, :map, required: true, doc: "the map of flash messages" - attr :id, :string, default: "flash-group", doc: "the optional id of flash container" - - def flash_group(assigns) do - ~H""" -
- <.flash kind={:info} title={gettext("Success!")} flash={@flash} /> - <.flash kind={:error} title={gettext("Error!")} flash={@flash} /> - <.flash - id="client-error" - kind={:error} - title={gettext("We can't find the internet")} - phx-disconnected={show(".phx-client-error #client-error")} - phx-connected={hide("#client-error")} - hidden - > - <%= gettext("Attempting to reconnect") %> - <.icon name="hero-arrow-path" class="tw-ml-1 tw-h-3 tw-w-3 tw-animate-spin" /> - - - <.flash - id="server-error" - kind={:error} - title={gettext("Something went wrong!")} - phx-disconnected={show(".phx-server-error #server-error")} - phx-connected={hide("#server-error")} - hidden - > - <%= gettext("Hang in there while we get back on track") %> - <.icon name="hero-arrow-path" class="tw-ml-1 tw-h-3 tw-w-3 tw-animate-spin" /> - -
- """ - end - - @doc """ - Renders a simple form. - - ## Examples - - <.simple_form for={@form} phx-change="validate" phx-submit="save"> - <.input field={@form[:email]} label="Email"/> - <.input field={@form[:username]} label="Username" /> - <:actions> - <.button>Save - - - """ - attr :for, :any, required: true, doc: "the data structure for the form" - attr :as, :any, default: nil, doc: "the server side parameter to collect all input under" - - attr :rest, :global, - include: ~w(autocomplete name rel action enctype method novalidate target multipart), - doc: "the arbitrary HTML attributes to apply to the form tag" - - slot :inner_block, required: true - slot :actions, doc: "the slot for form actions, such as a submit button" - - def simple_form(assigns) do - ~H""" - <.form :let={f} for={@for} as={@as} {@rest}> -
- <%= render_slot(@inner_block, f) %> -
- <%= render_slot(action, f) %> -
-
- - """ - end - - @doc """ - Renders a button. - - ## Examples - - <.button>Send! - <.button phx-click="go" class="tw-ml-2">Send! - """ - attr :type, :string, default: nil - attr :class, :string, default: nil - attr :rest, :global, include: ~w(disabled form name value) - - slot :inner_block, required: true - - def button(assigns) do - ~H""" - - """ - end - - @doc """ - Renders an input with label and error messages. - - A `Phoenix.HTML.FormField` may be passed as argument, - which is used to retrieve the input name, id, and values. - Otherwise all attributes may be passed explicitly. - - ## Types - - This function accepts all HTML input types, considering that: - - * You may also set `type="select"` to render a ` - - <%= @label %> - - <.error :for={msg <- @errors}><%= msg %> -
- """ - end - - def input(%{type: "select"} = assigns) do - ~H""" -
- <.label for={@id}><%= @label %> - - <.error :for={msg <- @errors}><%= msg %> -
- """ - end - - def input(%{type: "textarea"} = assigns) do - ~H""" -
- <.label for={@id}><%= @label %> - - <.error :for={msg <- @errors}><%= msg %> -
- """ - end - - # All other inputs text, datetime-local, url, password, etc. are handled here... - def input(assigns) do - ~H""" -
- <.label for={@id}><%= @label %> - - <.error :for={msg <- @errors}><%= msg %> -
- """ - end - - @doc """ - Renders a label. - """ - attr :for, :string, default: nil - slot :inner_block, required: true - - def label(assigns) do - ~H""" - - """ - end - - @doc """ - Generates a generic error message. - """ - slot :inner_block, required: true - - def error(assigns) do - ~H""" -

- <.icon name="hero-exclamation-circle-mini" class="tw-mt-0.5 tw-h-5 tw-w-5 tw-flex-none" /> - <%= render_slot(@inner_block) %> -

- """ - end - - @doc """ - Renders a header with title. - """ - attr :class, :string, default: nil - - slot :inner_block, required: true - slot :subtitle - slot :actions - - def header(assigns) do - ~H""" -
-
-

- <%= render_slot(@inner_block) %> -

-

- <%= render_slot(@subtitle) %> -

-
-
<%= render_slot(@actions) %>
-
- """ - end - - @doc ~S""" - Renders a table with generic styling. - - ## Examples - - <.table id="users" rows={@users}> - <:col :let={user} label="id"><%= user.id %> - <:col :let={user} label="username"><%= user.username %> - - """ - attr :id, :string, required: true - attr :rows, :list, required: true - attr :row_id, :any, default: nil, doc: "the function for generating the row id" - attr :row_click, :any, default: nil, doc: "the function for handling phx-click on each row" - - attr :row_item, :any, - default: &Function.identity/1, - doc: "the function for mapping each row before calling the :col and :action slots" - - slot :col, required: true do - attr :label, :string - end - - slot :action, doc: "the slot for showing user actions in the last table column" - - def table(assigns) do - assigns = - with %{rows: %Phoenix.LiveView.LiveStream{}} <- assigns do - assign(assigns, row_id: assigns.row_id || fn {id, _item} -> id end) - end - - ~H""" -
- - - - - - - - - - - - - -
- <%= col[:label] %> - - <%= gettext("Actions") %> -
-
- - - <%= render_slot(col, @row_item.(row)) %> - -
-
-
- - - <%= render_slot(action, @row_item.(row)) %> - -
-
-
- """ - end - - @doc """ - Renders a data list. - - ## Examples - - <.list> - <:item title="Title"><%= @post.title %> - <:item title="Views"><%= @post.views %> - - """ - slot :item, required: true do - attr :title, :string, required: true - end - - def list(assigns) do - ~H""" -
-
-
-
<%= item.title %>
-
<%= render_slot(item) %>
-
-
-
- """ - end - - @doc """ - Renders a back navigation link. - - ## Examples - - <.back navigate={~p"/posts"}>Back to posts - """ - attr :navigate, :any, required: true - slot :inner_block, required: true - - def back(assigns) do - ~H""" -
- <.link - navigate={@navigate} - class="tw-text-sm tw-font-semibold tw-leading-6 tw-text-zinc-900 tw-hover:text-zinc-700" - > - <.icon name="hero-arrow-left-solid" class="tw-h-3 tw-w-3" /> - <%= render_slot(@inner_block) %> - -
- """ - end - - @doc """ - Renders a [Heroicon](https://heroicons.com). - - Heroicons come in three styles – outline, solid, and mini. - By default, the outline style is used, but solid and mini may - be applied by using the `-solid` and `-mini` suffix. - - You can customize the size and colors of the icons by setting - width, height, and background color classes. - - Icons are extracted from the `deps/heroicons` directory and bundled within - your compiled app.css by the plugin in your `assets/tailwind.config.js`. - - ## Examples - - <.icon name="hero-x-mark-solid" /> - <.icon name="hero-arrow-path" class="tw-ml-1 tw-w-3 tw-h-3 tw-animate-spin" /> - """ - attr :name, :string, required: true - attr :class, :string, default: nil - - def icon(%{name: "hero-" <> _} = assigns) do - ~H""" - - """ - end - - ## JS Commands - - def show(js \\ %JS{}, selector) do - JS.show(js, - to: selector, - time: 300, - transition: - {"tw-transition-all tw-transform tw-ease-out tw-duration-300", - "tw-opacity-0 tw-translate-y-4 tw-sm:translate-y-0 tw-sm:scale-95", - "tw-opacity-100 tw-translate-y-0 tw-sm:scale-100"} - ) - end - - def hide(js \\ %JS{}, selector) do - JS.hide(js, - to: selector, - time: 200, - transition: - {"tw-transition-all tw-transform tw-ease-in tw-duration-200", - "tw-opacity-100 tw-translate-y-0 tw-sm:scale-100", - "tw-opacity-0 tw-translate-y-4 tw-sm:translate-y-0 tw-sm:scale-95"} - ) - end - - def show_modal(js \\ %JS{}, id) when is_binary(id) do - js - |> JS.show(to: "##{id}") - |> JS.show( - to: "##{id}-bg", - time: 300, - transition: - {"tw-transition-all tw-transform tw-ease-out tw-duration-300", "tw-opacity-0", - "tw-opacity-100"} - ) - |> show("##{id}-container") - |> JS.add_class("tw-overflow-hidden", to: "body") - |> JS.focus_first(to: "##{id}-content") - end - - def hide_modal(js \\ %JS{}, id) do - js - |> JS.hide( - to: "##{id}-bg", - transition: - {"tw-transition-all tw-transform tw-ease-in tw-duration-200", "tw-opacity-100", - "tw-opacity-0"} - ) - |> hide("##{id}-container") - |> JS.hide(to: "##{id}", transition: {"tw-block", "tw-block", "tw-hidden"}) - |> JS.remove_class("tw-overflow-hidden", to: "body") - |> JS.pop_focus() - end - - @doc """ - Translates an error message using gettext. - """ - def translate_error({msg, opts}) do - # When using gettext, we typically pass the strings we want - # to translate as a static argument: - # - # # Translate the number of files with plural rules - # dngettext("errors", "1 file", "%{count} files", count) - # - # However the error messages in our forms and APIs are generated - # dynamically, so we need to translate them by calling Gettext - # with our gettext backend as first argument. Translations are - # available in the errors.po file (as we use the "errors" domain). - if count = opts[:count] do - Gettext.dngettext(HelloWeb.Gettext, "errors", msg, msg, count, opts) - else - Gettext.dgettext(HelloWeb.Gettext, "errors", msg, opts) - end - end - - @doc """ - Translates the errors for a field from a keyword list of errors. - """ - def translate_errors(errors, field) when is_list(errors) do - for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts}) - end -end From 31a17da5c24b47b999db81c889bd5d8c3af456d9 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Tue, 17 Sep 2024 15:54:41 -0400 Subject: [PATCH 06/13] refactor(TripPlannerForm): use LiveComponent --- .../ts/phoenix-hooks/algolia-autocomplete.ts | 4 +- lib/dotcom/trip_plan/input_form.ex | 58 ++++-- .../live_components/trip_planner_form.ex | 194 ++++++++++++++++++ lib/dotcom_web/components/trip_planner.ex | 98 --------- lib/dotcom_web/live/trip_planner.ex | 58 ++---- test/dotcom/trip_plan/input_form_test.exs | 7 +- .../trip_planner/trip_planner_form_test.exs | 23 +++ .../components/trip_planner_test.exs | 90 -------- test/dotcom_web/live/trip_planner_test.exs | 101 +++++++++ 9 files changed, 380 insertions(+), 253 deletions(-) create mode 100644 lib/dotcom_web/components/live_components/trip_planner_form.ex delete mode 100644 lib/dotcom_web/components/trip_planner.ex create mode 100644 test/dotcom_web/components/live_components/trip_planner/trip_planner_form_test.exs delete mode 100644 test/dotcom_web/components/trip_planner_test.exs create mode 100644 test/dotcom_web/live/trip_planner_test.exs diff --git a/assets/ts/phoenix-hooks/algolia-autocomplete.ts b/assets/ts/phoenix-hooks/algolia-autocomplete.ts index 78676ff0ec..c145675e09 100644 --- a/assets/ts/phoenix-hooks/algolia-autocomplete.ts +++ b/assets/ts/phoenix-hooks/algolia-autocomplete.ts @@ -23,7 +23,7 @@ const AlgoliaAutocomplete: Partial = { const pushToLiveView = (data: Partial): void => { if (hook.el.querySelector("[data-config='trip-planner']")) { // this will fail outside of a LiveView, that's fine - hook.pushEventTo(hook.el, "map_change", { + hook.pushEvent("map_change", { id: hook.el.id, ...data }); @@ -46,8 +46,6 @@ const AlgoliaAutocomplete: Partial = { }) ); - // side effect: dispatch event to LV to get initial map markers - pushToLiveView(inputValues); return inputValues.name || ""; }; diff --git a/lib/dotcom/trip_plan/input_form.ex b/lib/dotcom/trip_plan/input_form.ex index abfa1e32dc..83eb4b54c2 100644 --- a/lib/dotcom/trip_plan/input_form.ex +++ b/lib/dotcom/trip_plan/input_form.ex @@ -8,44 +8,52 @@ defmodule Dotcom.TripPlan.InputForm do use TypedEctoSchema import Ecto.Changeset + @valid_modes [:commuter_rail, :subway, :bus, :ferry] + @time_types [:now, :leave_at, :arrive_by] + @error_messages %{ from: "Please specify an origin location.", to: "Please add a destination.", - from_to_same: "Please select a destination at a different location from the origin." + from_to_same: "Please select a destination at a different location from the origin.", + modes: "Please select at least one mode of transit.", + datetime: "Please specify a date and time in the future or select 'Now'." } @primary_key false typed_embedded_schema do embeds_one(:from, __MODULE__.Location) embeds_one(:to, __MODULE__.Location) + field(:datetime_type, Ecto.Enum, values: @time_types) + field(:datetime, :naive_datetime) + field(:modes, {:array, Ecto.Enum}, values: @valid_modes) + field(:wheelchair, :boolean, default: true) end + def time_types, do: @time_types + def valid_modes, do: @valid_modes + def changeset(params \\ %{}) do changeset(%__MODULE__{}, params) end def changeset(form, params) do form - |> cast(params, []) + |> cast(params, [:datetime_type, :datetime, :modes, :wheelchair]) |> cast_embed(:from, required: true) |> cast_embed(:to, required: true) end def validate_params(params) do - changes = - params - |> changeset() - |> update_change(:from, &update_location_change/1) - |> update_change(:to, &update_location_change/1) - |> validate_required(:from, message: error_message(:from)) - |> validate_required(:to, message: error_message(:to)) - |> validate_same_locations() - - if changes.errors == [] do - changes - else - %Ecto.Changeset{changes | action: :update} - end + params + |> changeset() + |> update_change(:from, &update_location_change/1) + |> update_change(:to, &update_location_change/1) + |> validate_required(:from, message: error_message(:from)) + |> validate_required(:to, message: error_message(:to)) + |> validate_required([:datetime_type, :modes, :wheelchair]) + |> validate_same_locations() + |> validate_length(:modes, min: 1, message: error_message(:modes)) + |> validate_chosen_datetime() end # make the parent field blank if the location isn't valid @@ -66,6 +74,24 @@ defmodule Dotcom.TripPlan.InputForm do end end + defp validate_chosen_datetime(changeset) do + case get_field(changeset, :datetime_type) do + :now -> + force_change(changeset, :datetime, NaiveDateTime.local_now()) + + _ -> + changeset + |> validate_change(:datetime, &validate_datetime/2) + end + end + + defp validate_datetime(field, date) do + case Timex.compare(date, Util.now(), :hours) do + -1 -> [{field, error_message(:datetime)}] + _ -> [] + end + end + def error_message(key), do: @error_messages[key] defmodule Location do diff --git a/lib/dotcom_web/components/live_components/trip_planner_form.ex b/lib/dotcom_web/components/live_components/trip_planner_form.ex new file mode 100644 index 0000000000..1b6f872191 --- /dev/null +++ b/lib/dotcom_web/components/live_components/trip_planner_form.ex @@ -0,0 +1,194 @@ +defmodule DotcomWeb.Components.LiveComponents.TripPlannerForm do + @moduledoc """ + A form to plan trips. + """ + use DotcomWeb, :live_component + + import DotcomWeb.ViewHelpers, only: [mode_name: 1, svg: 1] + import Phoenix.HTML.Form, only: [input_name: 2, input_value: 2, input_id: 2] + + alias Dotcom.TripPlan.InputForm + + @form_defaults %{ + "datetime_type" => :now, + "datetime" => NaiveDateTime.local_now(), + "modes" => [:commuter_rail, :subway, :bus, :ferry], + "wheelchair" => true + } + + @impl true + def mount(socket) do + form = + %InputForm{} + |> InputForm.changeset(@form_defaults) + |> to_form() + + {:ok, + assign(socket, %{ + form: form, + location_keys: InputForm.Location.fields(), + show_datepicker: false + })} + end + + @impl true + def render(assigns) do + ~H""" +
+ <.form + :let={f} + for={@form} + method="get" + phx-change="validate" + phx-submit="save_form" + phx-target={@myself} + > +
+ <.algolia_autocomplete + config_type="trip-planner" + placeholder="Enter a location" + id={"#{@form_name}--#{field}"} + > + <.inputs_for :let={location_f} field={f[field]} skip_hidden={true}> + + + <.form_error :for={{msg, _} <- f[field].errors} :if={used_input?(f[field])}> + <%= msg %> + + +
+ <.fieldset legend="When"> + <.input_group + id={input_id(@form, :datetime_type)} + field={f[:datetime_type]} + type="radio" + phx-click="toggle_datepicker" + phx-target={@myself} + phx-update="ignore" + > + <:input_item + :for={type <- Ecto.Enum.values(InputForm, :datetime_type)} + id={input_name(@form, :datetime_type) <> "_#{type}"} + value={type} + checked={input_value(@form, :datetime_type) == type} + /> + + + <.form_error + :for={{msg, _} <- f[:datetime_type].errors} + :if={used_input?(f[:datetime_type])} + > + <%= msg %> + + <.form_label :if={@show_datepicker} for="timepick"> + + Date and time to leave at or arrive by + + <.form_error + :for={{msg, _} <- f[:datetime_type].errors} + :if={used_input?(f[:datetime_type])} + > + <%= msg %> + + <.form_error :for={{msg, _} <- f[:datetime].errors} :if={used_input?(f[:datetime])}> + <%= msg %> + + + <.fieldset legend="Modes"> + <.accordion open> + <:heading> + <%= input_value(@form, :modes) |> selected_modes() %> + + <:content> + <.mode_selector field={f[:modes]} modes={modes()} /> + + <:extra :if={used_input?(f[:modes])}> + <.form_error :for={{msg, _} <- f[:modes].errors}> + <%= msg %> + + + + +
+ <.form_input type="checkbox" field={f[:wheelchair]} label="Prefer accessible routes" /> + <%= svg("icon-accessible-small.svg") %> +
+ <.button type="submit" phx-disable-with="Planning your trip..."> + Get trip suggestions + + +
+ """ + end + + @impl true + def handle_event("toggle_datepicker", %{"value" => datetime_value}, socket) do + {:noreply, assign(socket, :show_datepicker, datetime_value !== "now")} + end + + def handle_event("validate", %{"input_form" => params}, socket) do + form = + params + |> InputForm.validate_params() + |> Phoenix.Component.to_form() + + {:noreply, assign(socket, %{form: form})} + end + + def handle_event("save_form", %{"input_form" => params}, socket) do + params + |> InputForm.validate_params() + |> Ecto.Changeset.apply_action(:update) + |> case do + {:ok, data} -> + _ = socket.assigns.on_submit.(data) + + data + |> Ecto.Changeset.change() + |> Phoenix.Component.to_form() + + {:error, changeset} -> + changeset + |> Phoenix.Component.to_form() + end + |> then(fn form -> + {:noreply, assign(socket, %{form: form})} + end) + end + + defp modes do + InputForm + |> Ecto.Enum.values(:modes) + |> Enum.map(&{mode_name(&1), &1}) + end + + defp selected_modes([:commuter_rail, :subway, :bus, :ferry]) do + "All modes" + end + + defp selected_modes([]), do: "No transit modes selected" + + defp selected_modes([mode]), do: mode_name(mode) <> " Only" + defp selected_modes([mode1, mode2]), do: mode_name(mode1) <> " and " <> mode_name(mode2) + + defp selected_modes(modes) do + modes + |> Enum.map(&mode_name/1) + |> Enum.intersperse(", ") + |> List.insert_at(-2, "and ") + |> Enum.join("") + end +end diff --git a/lib/dotcom_web/components/trip_planner.ex b/lib/dotcom_web/components/trip_planner.ex deleted file mode 100644 index 41dbedfbcb..0000000000 --- a/lib/dotcom_web/components/trip_planner.ex +++ /dev/null @@ -1,98 +0,0 @@ -defmodule DotcomWeb.Components.TripPlannerForm do - @moduledoc """ - Reusable components mainly used for the Trip Planner - """ - use DotcomWeb, :component - - alias Dotcom.TripPlan.InputForm - - attr :id, :string - attr :params, :map, default: %{} - attr :phx_submit_handler, :string, default: nil - attr :on_validated_pid, :any - - attr :do_validation, :boolean, - default: false, - doc: "Whether to run the form validation on render." - - @doc """ - A form to plan trips. Use in a LiveView and specify the phx-action: - - ``` <.TripPlanner.input_form params={%{}} id="widget" phx_submit_handler="my_form_save_event" /> ``` - - With no phx-action provided, we'll assume we're outside a LiveView, and will - use an action to submit to the trip planner page. - """ - def input_form(assigns) do - assigns = - assigns - |> assign(:action, assign_action(assigns)) - |> assign(:form, create_form(assigns)) - |> assign(:location_keys, InputForm.Location.fields()) - - ~H""" - <.form - :let={f} - for={@form} - action={@action} - method="get" - phx-change="input_change" - phx-submit={@phx_submit_handler} - > -
- <.algolia_autocomplete - config_type="trip-planner" - placeholder="Enter a location" - id={"#{@id}--#{field}"} - > - <.inputs_for :let={location_f} field={f[field]} skip_hidden={true}> - - -

- <%= msg %> -

- -
- - - """ - end - - defp create_form(%{do_validation: true, params: params, on_validated_pid: on_validated_pid}) - when is_pid(on_validated_pid) do - changeset = InputForm.validate_params(params) - - case Ecto.Changeset.apply_action(changeset, :insert) do - {:ok, data} -> - send(on_validated_pid, {:updated_form, data}) - - data - |> InputForm.changeset(%{}) - |> Phoenix.Component.to_form(as: "plan") - - {:error, changeset} -> - send(on_validated_pid, {:updated_form, nil}) - Phoenix.Component.to_form(changeset, as: "plan") - end - end - - defp create_form(%{params: params}) do - params - |> InputForm.changeset() - |> Phoenix.Component.to_form(as: "plan") - end - - defp assign_action(%{phx_submit_handler: handler}) when is_nil(handler), - do: "/preview/trip-planner" - - defp assign_action(_), do: nil -end diff --git a/lib/dotcom_web/live/trip_planner.ex b/lib/dotcom_web/live/trip_planner.ex index 01894cc657..61e656fd5b 100644 --- a/lib/dotcom_web/live/trip_planner.ex +++ b/lib/dotcom_web/live/trip_planner.ex @@ -7,22 +7,13 @@ defmodule DotcomWeb.Live.TripPlanner do use DotcomWeb, :live_view - import DotcomWeb.Components.TripPlannerForm + alias DotcomWeb.Components.LiveComponents.TripPlannerForm @form_id "trip-planner-form" @impl true - def mount(params, _session, socket) do - pid = self() - {:ok, assign(socket, :params, plan_params(params)) |> assign(:pid, pid)} - end - - defp plan_params(%{"plan" => params}), do: params - defp plan_params(_), do: %{} - - @impl true - def handle_params(params, _uri, socket) do - {:noreply, assign(socket, :params, plan_params(params))} + def mount(_params, _session, socket) do + {:ok, socket} end @impl true @@ -30,19 +21,17 @@ defmodule DotcomWeb.Live.TripPlanner do assigns = assigns |> assign_new(:submitted_values, fn -> nil end) - |> assign_new(:do_validation, fn -> false end) - |> assign(:form_id, @form_id) + |> assign(:form_name, @form_id) ~H"""

Trip Planner Preview

- <.input_form - params={@params} - id={@form_id} - do_validation={@do_validation} - on_validated_pid={@pid} - phx_submit_handler="save_form" + <.live_component + module={TripPlannerForm} + id={@form_name} + form_name={@form_name} + on_submit={fn data -> send(self(), {:updated_form, data}) end} /> <%= inspect(@submitted_values) %> @@ -63,38 +52,17 @@ defmodule DotcomWeb.Live.TripPlanner do end @impl true - def handle_event("input_change", %{"plan" => params}, socket) do - merged_params = - socket.assigns.params - |> Map.merge(params, fn _, a, b -> Map.merge(a, b) end) - - {:noreply, - assign(socket, %{ - do_validation: false, - params: merged_params - })} - end - - @impl true - def handle_event("save_form", %{"plan" => params}, socket) do - {:noreply, - socket - |> assign(:do_validation, true) - |> push_patch(to: path_with_params(params), replace: true)} + def handle_event(_event, _params, socket) do + {:noreply, socket} end - @impl true - def handle_event(_, _, socket), do: {:noreply, socket} - @impl true def handle_info({:updated_form, data}, socket) do {:noreply, assign(socket, :submitted_values, data)} end - defp path_with_params(params) do - %{"plan" => params} - |> Plug.Conn.Query.encode() - |> then(&("/preview/trip-planner?" <> &1)) + def handle_info(_info, socket) do + {:noreply, socket} end # Selected from list of popular locations diff --git a/test/dotcom/trip_plan/input_form_test.exs b/test/dotcom/trip_plan/input_form_test.exs index 5e8eaba902..b7a334b0b3 100644 --- a/test/dotcom/trip_plan/input_form_test.exs +++ b/test/dotcom/trip_plan/input_form_test.exs @@ -11,9 +11,14 @@ defmodule Dotcom.TripPlan.InputFormTest do "latitude" => "#{Faker.Address.latitude()}", "longitude" => "#{Faker.Address.longitude()}" } + @mode_params InputForm.valid_modes() @params %{ "from" => @from_params, - "to" => @to_params + "to" => @to_params, + "datetime_type" => Faker.Util.pick(InputForm.time_types()) |> to_string(), + "datetime" => Faker.DateTime.forward(4) |> to_string(), + "modes" => @mode_params |> Enum.map(&to_string/1), + "wheelchair" => Faker.Util.pick(["true", "false"]) } test "from & to fields are required" do diff --git a/test/dotcom_web/components/live_components/trip_planner/trip_planner_form_test.exs b/test/dotcom_web/components/live_components/trip_planner/trip_planner_form_test.exs new file mode 100644 index 0000000000..91dc28e6a3 --- /dev/null +++ b/test/dotcom_web/components/live_components/trip_planner/trip_planner_form_test.exs @@ -0,0 +1,23 @@ +defmodule DotcomWeb.Components.LiveComponents.TripPlannerFormTest do + use ExUnit.Case, async: true + + import Phoenix.LiveViewTest + alias DotcomWeb.Components.LiveComponents.TripPlannerForm + + test "renders the needed inputs" do + html = + render_component(TripPlannerForm, %{ + id: "my_form", + form_name: "my_form" + }) + + assert html =~ + ~s(
) + + assert html =~ ~s(name="input_form[from]) + assert html =~ ~s(name="input_form[to]) + assert html =~ ~s(name="input_form[datetime_type]) + assert html =~ ~s(name="input_form[wheelchair]) + assert html =~ ~s(name="input_form[modes]) + end +end diff --git a/test/dotcom_web/components/trip_planner_test.exs b/test/dotcom_web/components/trip_planner_test.exs deleted file mode 100644 index 40c09e922d..0000000000 --- a/test/dotcom_web/components/trip_planner_test.exs +++ /dev/null @@ -1,90 +0,0 @@ -defmodule DotcomWeb.Components.TripPlannerFormTest do - @moduledoc false - use ExUnit.Case - import Phoenix.LiveViewTest - import DotcomWeb.Components.TripPlannerForm - - describe "input_form" do - test "renders the needed inputs" do - html = - render_component(&input_form/1, %{ - id: "my_form" - }) - - assert html =~ ~s(
) - - assert html =~ ~s(name="plan[from]) - assert html =~ ~s(name="plan[to]) - end - - test "doesn't assign a form action if a submit handler provided" do - html = - render_component(&input_form/1, %{ - id: "my_form", - phx_submit_handler: "something" - }) - - refute html =~ ~s( from_lon, - "latitude" => from_lat - } - - to_lon = Faker.Address.longitude() - to_lat = Faker.Address.latitude() - - to_params = %{ - "longitude" => to_lon, - "latitude" => to_lat - } - - _ = - render_component(&input_form/1, %{ - id: "my_form", - do_validation: true, - on_validated_pid: pid, - params: %{ - "from" => from_params, - "to" => to_params - } - }) - - assert_receive {:updated_form, data} - - assert %Dotcom.TripPlan.InputForm{ - from: %Dotcom.TripPlan.InputForm.Location{ - latitude: ^from_lat, - longitude: ^from_lon - }, - to: %Dotcom.TripPlan.InputForm.Location{ - latitude: ^to_lat, - longitude: ^to_lon - } - } = data - end - end -end diff --git a/test/dotcom_web/live/trip_planner_test.exs b/test/dotcom_web/live/trip_planner_test.exs new file mode 100644 index 0000000000..c4749e96b5 --- /dev/null +++ b/test/dotcom_web/live/trip_planner_test.exs @@ -0,0 +1,101 @@ +defmodule DotcomWeb.Live.TripPlannerTest do + use DotcomWeb.ConnCase, async: true + + import Phoenix.LiveViewTest + + test "Preview version behind basic auth", %{conn: conn} do + conn = get(conn, ~p"/preview/trip-planner") + + {_header_name, header_value} = List.keyfind(conn.resp_headers, "www-authenticate", 0) + assert conn.status == 401 + assert header_value =~ "Basic" + end + + describe "Trip Planner" do + setup %{conn: conn} do + [username: username, password: password] = + Application.get_env(:dotcom, DotcomWeb.Router)[:basic_auth] + + {:ok, view, html} = + conn + |> put_req_header("authorization", "Basic " <> Base.encode64("#{username}:#{password}")) + |> live(~p"/preview/trip-planner") + + %{html: html, view: view} + end + + test "toggles the date input when changing from 'now'", %{html: html, view: view} do + date_input = ~s(name="input_form[datetime]") + refute html =~ date_input + + html = + view + |> element("input[value=arrive_by]") + |> render_click() + + assert html =~ date_input + + html = + view + |> element("input[value=now]") + |> render_click() + + refute html =~ date_input + end + + test "summarizes the selected modes", %{view: view, html: html} do + assert html =~ "All modes" + + html = + view + |> element("form") + |> render_change(%{ + _target: ["input_form", "modes"], + input_form: %{modes: [:commuter_rail, :subway, :ferry]} + }) + + assert html =~ "Commuter Rail, Subway, and Ferry" + + html = + view + |> element("form") + |> render_change(%{_target: ["input_form", "modes"], input_form: %{modes: [:subway]}}) + + assert html =~ "Subway Only" + + html = + view + |> element("form") + |> render_change(%{ + _target: ["input_form", "modes"], + input_form: %{modes: [:subway, :bus]} + }) + + assert html =~ "Subway and Bus" + end + + test "shows errors on form submit", %{view: view} do + html = + view + |> element("form") + |> render_submit() + + assert html =~ "Please add a destination." + end + + test "pushes updated location to the map", %{view: view} do + updated_location = %{ + "latitude" => Faker.Address.latitude(), + "longitude" => Faker.Address.longitude(), + "name" => Faker.Company.name() + } + + id = Faker.Internet.slug() + + view + |> render_hook(:map_change, Map.put_new(updated_location, "id", id)) + + assert_push_event(view, ^id, ^updated_location) + end + end +end From 2126b5648797d8cedf38ba8a78a1f40dcaa9d073 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Thu, 19 Sep 2024 09:45:08 -0400 Subject: [PATCH 07/13] actually update mbta_metro --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 7b67d1c961..18a9c1a9a1 100644 --- a/mix.lock +++ b/mix.lock @@ -58,7 +58,7 @@ "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, "makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, "makeup_html": {:hex, :makeup_html, "0.1.1", "c3d4abd39d5f7e925faca72ada6e9cc5c6f5fa7cd5bc0158315832656cf14d7f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "44f2a61bc5243645dd7fafeaa6cc28793cd22f3c76b861e066168f9a5b2c26a4"}, - "mbta_metro": {:hex, :mbta_metro, "0.0.1", "8148e2feeb32c1f361daf43f210361beb07bf432c5caa03ff08d931e68e4fef4", [:mix], [{:heroicons, "0.5.6", [hex: :heroicons, repo: "hexpm", optional: false]}, {:phoenix, "1.7.14", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, "1.0.0-rc.6", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_storybook, "0.6.4", [hex: :phoenix_storybook, repo: "hexpm", optional: false]}], "hexpm", "8fcc05f5a5eadb052233c5ac8a10929f3df8c5b264791505156c82c4b1403fc2"}, + "mbta_metro": {:hex, :mbta_metro, "0.0.2", "35d4ae898b7c6d7d6d81a7114fa2cf843d2b5f0ac6c90d6ceffe62106c661c24", [:mix], [{:heroicons, "0.5.6", [hex: :heroicons, repo: "hexpm", optional: false]}, {:phoenix, "1.7.14", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, "1.0.0-rc.6", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_storybook, "0.6.4", [hex: :phoenix_storybook, repo: "hexpm", optional: false]}], "hexpm", "df85a11f7af4b1e8335ca38c5fb1e4065f89d8b509970b2e0d473b4ec1676c61"}, "meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, From acc1d921530c392d768ffc36aed93b38c4ae3f1a Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Thu, 19 Sep 2024 09:46:21 -0400 Subject: [PATCH 08/13] chore: remove old Tailwind prefix --- assets/js/algolia-result.js | 2 +- .../__snapshots__/config-test.ts.snap | 30 +++++++++---------- .../__snapshots__/templates-test.tsx.snap | 30 +++++++++---------- .../ts/ui/autocomplete/templates/algolia.tsx | 20 ++++++------- .../ui/autocomplete/templates/geolocation.tsx | 4 +-- .../ts/ui/autocomplete/templates/location.tsx | 8 ++--- .../ts/ui/autocomplete/templates/popular.tsx | 10 +++---- 7 files changed, 52 insertions(+), 52 deletions(-) diff --git a/assets/js/algolia-result.js b/assets/js/algolia-result.js index 0a13b756ed..f4a12ad92f 100644 --- a/assets/js/algolia-result.js +++ b/assets/js/algolia-result.js @@ -484,7 +484,7 @@ function _stopIcons(hit, type) { .split(", ") .map( num => - `${num}` + `${num}` ) .join(""); }); diff --git a/assets/ts/ui/autocomplete/__tests__/__snapshots__/config-test.ts.snap b/assets/ts/ui/autocomplete/__tests__/__snapshots__/config-test.ts.snap index bcee7c7c75..c416ba69a1 100644 --- a/assets/ts/ui/autocomplete/__tests__/__snapshots__/config-test.ts.snap +++ b/assets/ts/ui/autocomplete/__tests__/__snapshots__/config-test.ts.snap @@ -7,24 +7,24 @@ exports[`Algolia template handles route item 1`] = ` href="/schedules/111" >
 
@@ -44,20 +44,20 @@ exports[`Location template renders 1`] = ` class="aa-ItemContent" >
Town, MA
@@ -76,13 +76,13 @@ exports[`Popular template renders 1`] = ` class="aa-ItemContent" >
Town, MA
diff --git a/assets/ts/ui/autocomplete/__tests__/__snapshots__/templates-test.tsx.snap b/assets/ts/ui/autocomplete/__tests__/__snapshots__/templates-test.tsx.snap index bcee7c7c75..c416ba69a1 100644 --- a/assets/ts/ui/autocomplete/__tests__/__snapshots__/templates-test.tsx.snap +++ b/assets/ts/ui/autocomplete/__tests__/__snapshots__/templates-test.tsx.snap @@ -7,24 +7,24 @@ exports[`Algolia template handles route item 1`] = ` href="/schedules/111" >
 
@@ -44,20 +44,20 @@ exports[`Location template renders 1`] = ` class="aa-ItemContent" >
Town, MA
@@ -76,13 +76,13 @@ exports[`Popular template renders 1`] = ` class="aa-ItemContent" >
Town, MA
diff --git a/assets/ts/ui/autocomplete/templates/algolia.tsx b/assets/ts/ui/autocomplete/templates/algolia.tsx index 786bac91ec..0eeea6ad18 100644 --- a/assets/ts/ui/autocomplete/templates/algolia.tsx +++ b/assets/ts/ui/autocomplete/templates/algolia.tsx @@ -78,17 +78,17 @@ const AlgoliaItemTemplate: SourceTemplates["item"] = ({ ? contentIcon(item) : getIcon(item, indexName); return ( -
-
-
+
+
+
-
+
{components.Highlight({ hit: item, @@ -96,13 +96,13 @@ const AlgoliaItemTemplate: SourceTemplates["item"] = ({ })} {isStopItem(item) && !item.stop["station?"] && ( - + #{item.stop.id} )}   {isRouteItem(item) && item.route.type === 3 && ( - + {components.Highlight({ hit: item, attribute: ["route", "long_name"] @@ -112,8 +112,8 @@ const AlgoliaItemTemplate: SourceTemplates["item"] = ({
{!isContentItem(item) && featureIcons.length > 0 && ( -
-
+
+
{featureIcons.map((feature: string) => ( ["item"] = ({ ))}
{isStopItem(item) && ( -
+
{`${item.stop.municipality}, ${ item.stop.address ? stateAbbr(item.stop.address) : "MA" }`} diff --git a/assets/ts/ui/autocomplete/templates/geolocation.tsx b/assets/ts/ui/autocomplete/templates/geolocation.tsx index be01a5095a..13dc0fa74e 100644 --- a/assets/ts/ui/autocomplete/templates/geolocation.tsx +++ b/assets/ts/ui/autocomplete/templates/geolocation.tsx @@ -69,7 +69,7 @@ export function GeolocationComponent(props: { if (loading) { return (
-
+