├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ └── R-CMD-check.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── components.R ├── dependencies.R ├── inputs.R ├── reactRouterExample.R └── reexports.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── inst ├── examples │ ├── basic │ │ └── app.R │ ├── bslib │ │ └── app.R │ └── dynamic-segment │ │ └── app.R └── reactRouter-6.30.0 │ ├── react-router-dom.js │ └── react-router-dom.js.LICENSE.txt ├── js ├── package.json ├── src │ ├── index.js │ └── inputs.jsx ├── webpack.config.js └── yarn.lock ├── man ├── BrowserRouter.Rd ├── HashRouter.Rd ├── Link.Rd ├── MemoryRouter.Rd ├── NavLink.Rd ├── Navigate.Rd ├── Outlet.Rd ├── Route.Rd ├── Routes.Rd ├── component.Rd ├── figures │ ├── logo.png │ ├── reactRouter-with-bslib.png │ └── reactRouter-with-shinyMaterialUI.png ├── reactRouterDependency.Rd ├── reactRouterExample.Rd └── reexports.Rd ├── pkgdown └── favicon │ ├── apple-touch-icon.png │ ├── favicon-96x96.png │ ├── favicon.ico │ ├── favicon.svg │ ├── site.webmanifest │ ├── web-app-manifest-192x192.png │ └── web-app-manifest-512x512.png ├── reactRouter.Rproj ├── tests ├── testthat.R └── testthat │ ├── setup-shinytest2.R │ ├── test-HashRouter.R │ └── test-apps │ └── HashRouter │ └── App.R └── vignettes ├── .gitignore └── introduction.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^js$ 4 | ^README\.Rmd$ 5 | ^LICENSE\.md$ 6 | _\.new\.png$ 7 | ^\.github$ 8 | ^_pkgdown.yml 9 | ^pkgdown 10 | ^docs 11 | ^data-raw 12 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | 8 | name: R-CMD-check.yaml 9 | 10 | permissions: read-all 11 | 12 | jobs: 13 | R-CMD-check: 14 | runs-on: ${{ matrix.config.os }} 15 | 16 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 17 | 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | config: 22 | - {os: macos-latest, r: 'release'} 23 | - {os: windows-latest, r: 'release'} 24 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 25 | - {os: ubuntu-latest, r: 'release'} 26 | - {os: ubuntu-latest, r: 'oldrel-1'} 27 | 28 | env: 29 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 30 | R_KEEP_PKG_SOURCE: yes 31 | 32 | steps: 33 | - uses: actions/checkout@v4 34 | 35 | - uses: r-lib/actions/setup-pandoc@v2 36 | 37 | - uses: r-lib/actions/setup-r@v2 38 | with: 39 | r-version: ${{ matrix.config.r }} 40 | http-user-agent: ${{ matrix.config.http-user-agent }} 41 | use-public-rspm: true 42 | 43 | - uses: r-lib/actions/setup-r-dependencies@v2 44 | with: 45 | extra-packages: any::rcmdcheck 46 | needs: check 47 | 48 | - uses: r-lib/actions/check-r-package@v2 49 | with: 50 | upload-snapshots: true 51 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # {shinytest2}: Ignore new debug snapshots for `$expect_values()` 2 | *_.new.png 3 | .Rproj.user 4 | .Rhistory 5 | .Rdata 6 | .httr-oauth 7 | .DS_Store 8 | .quarto 9 | 10 | js/node_modules 11 | js/README.md 12 | docs 13 | inst/doc 14 | data-raw 15 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: reactRouter 2 | Type: Package 3 | Title: 'React Router' for 'shiny' Apps and 'Quarto' 4 | Version: 0.1.1 5 | Authors@R: c( 6 | person(given = "Felix", family = "Luginbuhl", role = c("aut", "cre"), email = "felix.luginbuhl@protonmail.ch", comment = c(ORCID = "0009-0008-6625-2899")), 7 | person(given = "Andryas", family = "Waurzenczak", role = c("ctb")), 8 | person(family = "Shopify Inc.", role = c("ctb", "cph"), comment = "Shopify Inc. template ") 9 | ) 10 | Maintainer: Felix Luginbuhl 11 | Description: You can easily share url pages using 'React Router' in 'shiny' applications 12 | and 'Quarto' documents. The package wraps the 'react-router-dom' 'React' library and 13 | provides access to hash routing to navigate on multiple url pages. 14 | License: MIT + file LICENSE 15 | Encoding: UTF-8 16 | LazyData: true 17 | Depends: R (>= 3.4) 18 | Imports: 19 | htmltools, 20 | shiny, 21 | shiny.react, 22 | checkmate, 23 | uuid 24 | Suggests: 25 | testthat (>= 3.0.0), 26 | chromote (>= 0.1.1.9001), 27 | shinytest2, 28 | knitr, 29 | rmarkdown 30 | RoxygenNote: 7.3.2 31 | URL: https://felixluginbuhl.com/reactRouter/ 32 | BugReports: https://github.com/lgnbhl/reactRouter/issues 33 | Config/testthat/edition: 3 34 | VignetteBuilder: knitr 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2025 2 | COPYRIGHT HOLDER: reactRouter authors 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2025 reactRouter authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(BrowserRouter) 4 | export(HashRouter) 5 | export(JS) 6 | export(Link) 7 | export(Link.shinyInput) 8 | export(MemoryRouter) 9 | export(NavLink) 10 | export(NavLink.shinyInput) 11 | export(Navigate) 12 | export(Outlet) 13 | export(Route) 14 | export(Routes) 15 | export(reactRouterDependency) 16 | export(reactRouterExample) 17 | export(updateLink.shinyInput) 18 | export(updateNavLink.shinyInput) 19 | importFrom(shiny.react,JS) 20 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # reactRouter 0.1.1 2 | 3 | * add example with **bslib** 4 | 5 | # reactRouter 0.1.0 6 | 7 | * initial commit 8 | -------------------------------------------------------------------------------- /R/components.R: -------------------------------------------------------------------------------- 1 | #' Documentation template for components 2 | #' 3 | #' @param ... Props to pass to the component. 4 | #' The allowed props are listed below in the \bold{Details} section. 5 | #' 6 | #' @return 7 | #' Object with `shiny.tag` class suitable for use in the UI of a Shiny app. 8 | #' 9 | #' @keywords internal 10 | #' @name component 11 | NULL 12 | 13 | component <- function(name, module = 'react-router-dom') { 14 | function(...) shiny.react::reactElement( 15 | module = module, 16 | name = name, 17 | props = shiny.react::asProps(...), 18 | deps = reactRouterDependency() 19 | ) 20 | } 21 | 22 | #' HashRouter 23 | #' @rdname HashRouter 24 | #' @description \url{https://reactrouter.com/6.30.0/router-components/hash-router} 25 | #' @param ... Props to pass to element. 26 | #' @return A HashRouter component. 27 | #' @export 28 | HashRouter <- component('HashRouter') 29 | 30 | #' BrowserRouter 31 | #' @rdname BrowserRouter 32 | #' @description \url{https://reactrouter.com/6.30.0/router-components/browser-router} 33 | #' @param ... Props to pass to element. 34 | #' @return A BrowserRouter component. 35 | #' @export 36 | BrowserRouter <- component('BrowserRouter') 37 | 38 | #' MemoryRouter 39 | #' @rdname MemoryRouter 40 | #' @description \url{https://reactrouter.com/6.30.0/router-components/memory-router} 41 | #' @param ... Props to pass to element. 42 | #' @return A MemoryRouter component. 43 | #' @export 44 | MemoryRouter <- component('MemoryRouter') 45 | 46 | #' Route 47 | #' 48 | #' \url{https://reactrouter.com/6.30.0/components/route} 49 | #' 50 | #' Internally the `element` is wrapped in a `shiny::div()` 51 | #' with a UUID key so, in case R shiny is used, shiny can differentiate 52 | #' each element. 53 | #' 54 | #' @rdname Route 55 | #' @param ... Props to pass to element. 56 | #' @param element element wrapped in a `shiny::div()`. 57 | #' @param key By default uses a UUID key in the `div()` of the `element` arg. 58 | #' @return A Route component. 59 | #' @export 60 | Route <- function(..., element, key = uuid::UUIDgenerate()) { 61 | shiny.react::reactElement( 62 | module = "react-router-dom", 63 | name = "Route", 64 | props = shiny.react::asProps( 65 | ..., 66 | element = shiny::div( 67 | key = key, 68 | element 69 | ) 70 | ), 71 | deps = reactRouterDependency() 72 | ) 73 | } 74 | 75 | #' Link 76 | #' 77 | #' The `reloadDocument` can be used to skip client side routing and let the 78 | #' browser handle the transition normally (as if it were an ). In 79 | #' React Router v6 `reloadDocument` if `FALSE`, but given shiny behavior, the 80 | #' `Link()` function makes it `TRUE` by default. 81 | #' 82 | #' @rdname Link 83 | #' @param ... Props to pass to element. 84 | #' @param reloadDocument Boolean. Default TRUE. Let browser handle the transition normally 85 | #' @return A Link component. 86 | #' @export 87 | Link <- function(..., reloadDocument = TRUE) { 88 | shiny.react::reactElement( 89 | module = "react-router-dom", 90 | name = "Link", 91 | props = shiny.react::asProps( 92 | ..., 93 | reloadDocument = reloadDocument 94 | ), 95 | deps = reactRouterDependency() 96 | ) 97 | } 98 | 99 | #' Navigate 100 | #' @rdname Navigate 101 | #' @description \url{https://reactrouter.com/6.30.0/components/navigate} 102 | #' @param ... Props to pass to element. 103 | #' @return A Navigate component. 104 | #' @export 105 | Navigate <- component('Navigate') 106 | 107 | #' NavLink 108 | #' 109 | #' The `reloadDocument` can be used to skip client side routing and let the 110 | #' browser handle the transition normally (as if it were an ). In 111 | #' React Router v6 `reloadDocument` if `FALSE`, but given shiny behavior, the 112 | #' `NavLink()` function makes it `TRUE` by default. 113 | #' 114 | #' @rdname NavLink 115 | #' @param ... Props to pass to element. 116 | #' @param reloadDocument Boolean. Default TRUE. Let browser handle the transition normally 117 | #' @return A NavLink component. 118 | #' @export 119 | NavLink <- function(..., reloadDocument = TRUE) { 120 | shiny.react::reactElement( 121 | module = "react-router-dom", 122 | name = "NavLink", 123 | props = shiny.react::asProps( 124 | ..., 125 | reloadDocument = reloadDocument 126 | ), 127 | deps = reactRouterDependency() 128 | ) 129 | } 130 | 131 | 132 | #' Outlet 133 | #' @rdname Outlet 134 | #' @description \url{https://reactrouter.com/6.30.0/components/outlet} 135 | #' @param ... Props to pass to element. 136 | #' @return A Outlet component. 137 | #' @export 138 | Outlet <- component('Outlet') 139 | 140 | #' Routes 141 | #' @rdname Routes 142 | #' @description \url{https://reactrouter.com/6.30.0/components/routes} 143 | #' @param ... Props to pass to element. 144 | #' @return A Routes component. 145 | #' @export 146 | Routes <- component('Routes') 147 | -------------------------------------------------------------------------------- /R/dependencies.R: -------------------------------------------------------------------------------- 1 | #' react-router-dom JS dependency 2 | #' 3 | #' @return HTML dependency object. 4 | #' 5 | #' @export 6 | reactRouterDependency <- function() { 7 | htmltools::htmlDependency( 8 | name = "reactRouter", 9 | version = "0.0.1", 10 | package = "reactRouter", 11 | src = c(file = "reactRouter-6.30.0"), 12 | script = "react-router-dom.js" 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /R/inputs.R: -------------------------------------------------------------------------------- 1 | input_link <- function(name) { 2 | function(inputId, ..., reloadDocument = TRUE) { 3 | checkmate::assert_string(inputId) 4 | shiny.react::reactElement( 5 | module = "@/reactRouter", 6 | name = name, 7 | props = shiny.react::asProps(inputId = inputId, ..., reloadDocument = reloadDocument), 8 | deps = reactRouterDependency() 9 | ) 10 | } 11 | } 12 | 13 | #' Link 14 | #' @rdname Link 15 | #' @description \url{https://reactrouter.com/6.30.0/components/link} 16 | #' @param ... Props to pass to element. 17 | #' @param inputId ID of the component. 18 | #' @param reloadDocument Boolean. Default TRUE. Let browser handle the transition normally 19 | #' @param session Object passed as the `session` argument to Shiny server. 20 | #' @export 21 | Link.shinyInput <- function(inputId, ..., reloadDocument = TRUE) { 22 | checkmate::assert_string(inputId) 23 | checkmate::assert_logical(reloadDocument) 24 | shiny.react::reactElement( 25 | module = "@/reactRouter", 26 | name = "Link", 27 | props = shiny.react::asProps(inputId = inputId, ..., reloadDocument = reloadDocument), 28 | deps = reactRouterDependency() 29 | ) 30 | } 31 | 32 | #' @rdname Link 33 | #' @export 34 | updateLink.shinyInput <- shiny.react::updateReactInput 35 | 36 | #' NavLink 37 | #' @rdname NavLink 38 | #' @description \url{https://reactrouter.com/6.30.0/components/nav-link} 39 | #' @param ... Props to pass to element. 40 | #' @param inputId ID of the component. 41 | #' @param reloadDocument Boolean. Default TRUE. Let browser handle the transition normally 42 | #' @param session Object passed as the `session` argument to Shiny server. 43 | #' @export 44 | NavLink.shinyInput <- function(inputId, ..., reloadDocument = TRUE) { 45 | checkmate::assert_string(inputId) 46 | checkmate::assert_logical(reloadDocument) 47 | shiny.react::reactElement( 48 | module = "@/reactRouter", 49 | name = "NavLink", 50 | props = shiny.react::asProps(inputId = inputId, ..., reloadDocument = reloadDocument), 51 | deps = reactRouterDependency() 52 | ) 53 | } 54 | 55 | #' @rdname NavLink 56 | #' @export 57 | updateNavLink.shinyInput <- shiny.react::updateReactInput 58 | -------------------------------------------------------------------------------- /R/reactRouterExample.R: -------------------------------------------------------------------------------- 1 | #' Run reactRouterExample example 2 | #' 3 | #' Launch a Shiny example app or list the available examples. 4 | #' Use `reactRouter::reactRouterExample("basic")` to run a showcase app. 5 | #' 6 | #' @param example The name of the example to run, or `NULL` to retrieve the list of examples. 7 | #' @param ... Additional arguments to pass to `shiny::runApp()`. 8 | #' @return This function normally does not return; 9 | #' interrupt R to stop the application (usually by pressing Ctrl+C or Esc). 10 | #' 11 | #' @seealso [shiny.blueprint::runExample()] which this function is an adaptation. 12 | #' 13 | #' @export 14 | reactRouterExample <- function(example = NULL, ...) { 15 | examples <- system.file("examples", package = utils::packageName(), mustWork = TRUE) 16 | if (is.null(example)) { 17 | sub("\\.R$", "", list.files(examples)) 18 | } else { 19 | path <- file.path(examples, example) 20 | if (!grepl("\\.R$", path) && !file.exists(path)) { 21 | path <- paste0(path, ".R") 22 | } 23 | shiny::runApp(path, ...) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /R/reexports.R: -------------------------------------------------------------------------------- 1 | #' @importFrom shiny.react JS 2 | #' @export 3 | shiny.react::JS 4 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r message=FALSE, warning=FALSE, include=FALSE} 8 | # get JS dependencies 9 | dependencies <- jsonlite::fromJSON("js/package.json")$dependencies 10 | ``` 11 | 12 | # reactRouter 13 | 14 | 15 | [![CRAN status](https://www.r-pkg.org/badges/version/reactRouter)](https://CRAN.R-project.org/package=reactRouter) 16 | [![Grand total](https://cranlogs.r-pkg.org/badges/grand-total/reactRouter)](https://cran.r-project.org/package=reactRouter) 17 | [![R-CMD-check](https://github.com/lgnbhl/reactRouter/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/lgnbhl/reactRouter/actions/workflows/R-CMD-check.yaml) 18 | `r badger::badge_custom(names(dependencies)[1], dependencies[1], "blue", "https://reactrouter.com/6.30.0")` 19 | [![LinkedIn](https://img.shields.io/badge/LinkedIn-Follow-E4405F?style=social&logo=linkedin)](https://www.linkedin.com/in/FelixLuginbuhl) 20 | 21 | 22 | The goal of **reactRouter** is to provide a wrapper around [React Router (v6)](https://reactrouter.com/6.30.0). 23 | 24 | ### Usage 25 | 26 | You can easily add URL pages in Quarto document or R shiny like so: 27 | 28 | ```r 29 | library(reactRouter) 30 | 31 | HashRouter( 32 | NavLink(to = "/", "Main"), 33 | NavLink(to = "/analysis", "Analysis"), 34 | Routes( 35 | Route(path = "/", element = "Main content"), 36 | Route(path = "/analysis", element = "Analysis content") 37 | ) 38 | ) 39 | ``` 40 | 41 | ### Install 42 | 43 | ```r 44 | #remotes::install_github("lgnbhl/reactRouter") # development version 45 | 46 | install.packages("reactRouter") 47 | ``` 48 | 49 | ### Example 50 | 51 | Get started with a showcase example: 52 | 53 | ```r 54 | # print all examples available: reactRouterExample() 55 | reactRouterExample("dynamic-segment") 56 | ``` 57 | 58 | Read the vignette [here](https://felixluginbuhl.com/reactRouter/articles/introduction.html) for detailed use cases with Quarto and R Shiny. 59 | 60 | ### Contribute 61 | 62 | Would you like to contribute to the package? Have a look at the current [roadmap](https://github.com/users/lgnbhl/projects/2/views/1). 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # reactRouter 5 | 6 | 7 | 8 | [![CRAN 9 | status](https://www.r-pkg.org/badges/version/reactRouter)](https://CRAN.R-project.org/package=reactRouter) 10 | [![Grand 11 | total](https://cranlogs.r-pkg.org/badges/grand-total/reactRouter)](https://cran.r-project.org/package=reactRouter) 12 | [![R-CMD-check](https://github.com/lgnbhl/reactRouter/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/lgnbhl/reactRouter/actions/workflows/R-CMD-check.yaml) 13 | [![](https://img.shields.io/badge/react--router--dom-6.30.0-blue.svg)](https://reactrouter.com/6.30.0) 14 | [![LinkedIn](https://img.shields.io/badge/LinkedIn-Follow-E4405F?style=social&logo=linkedin)](https://www.linkedin.com/in/FelixLuginbuhl) 15 | 16 | 17 | The goal of **reactRouter** is to provide a wrapper around [React Router 18 | (v6)](https://reactrouter.com/6.30.0). 19 | 20 | ### Usage 21 | 22 | You can easily add URL pages in Quarto document or R shiny like so: 23 | 24 | ``` r 25 | library(reactRouter) 26 | 27 | HashRouter( 28 | NavLink(to = "/", "Main"), 29 | NavLink(to = "/analysis", "Analysis"), 30 | Routes( 31 | Route(path = "/", element = "Main content"), 32 | Route(path = "/analysis", element = "Analysis content") 33 | ) 34 | ) 35 | ``` 36 | 37 | ### Install 38 | 39 | ``` r 40 | #remotes::install_github("lgnbhl/reactRouter") # development version 41 | 42 | install.packages("reactRouter") 43 | ``` 44 | 45 | ### Example 46 | 47 | Get started with a showcase example: 48 | 49 | ``` r 50 | # print all examples available: reactRouterExample() 51 | reactRouterExample("basic") 52 | ``` 53 | 54 | Read the vignette 55 | [here](https://felixluginbuhl.com/reactRouter/articles/introduction.html) 56 | for detailed use cases with Quarto and R Shiny. 57 | 58 | ### Contribute 59 | 60 | Would you like to contribute to the package? Have a look at the current 61 | [roadmap](https://github.com/users/lgnbhl/projects/2/views/1). 62 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://felixluginbuhl.com/reactRouter 2 | template: 3 | bootstrap: 5 4 | bootswatch: litera 5 | ganalytics: UA-158089797-1 6 | bslib: 7 | primary: "#5c6bc0" 8 | 9 | authors: 10 | Felix Luginbuhl: 11 | href: "https://felixluginbuhl.com" 12 | 13 | navbar: 14 | left: 15 | - text: Home 16 | href: index.html 17 | - text: Get started 18 | href: articles/introduction.html 19 | - text: Reference 20 | href: reference/index.html 21 | - text: News 22 | href: news/index.html 23 | 24 | right: 25 | - icon: fa-linkedin 26 | href: https://www.linkedin.com/in/felixluginbuhl 27 | - icon: fa-twitter 28 | href: https://twitter.com/FelixLuginbuhl 29 | - icon: fa-github 30 | href: https://github.com/lgnbhl/reactRouter 31 | - icon: fa-home 32 | href: http://felixluginbuhl.com 33 | -------------------------------------------------------------------------------- /inst/examples/basic/app.R: -------------------------------------------------------------------------------- 1 | # https://github.com/remix-run/react-router/tree/dev/examples/basic 2 | 3 | library(shiny) 4 | library(reactRouter) 5 | 6 | Layout <- div( 7 | # A "layout route" is a good place to put markup you want to 8 | # share across all the pages on your site, like navigation. 9 | tags$nav( 10 | tags$ul( 11 | tags$li( 12 | reactRouter::Link(to = "/", "Home") 13 | ), 14 | tags$li( 15 | reactRouter::Link(to = "/about", "About") 16 | ), 17 | tags$li( 18 | reactRouter::Link(to = "/dashboard", "Dashboard") 19 | ), 20 | tags$li( 21 | reactRouter::Link(to = "/nothing-here", "Nothing Here") 22 | ) 23 | ) 24 | ), 25 | tags$hr(), 26 | # An renders whatever child route is currently active, 27 | # so you can think about this as a placeholder for 28 | # the child routes we defined above. 29 | reactRouter::Outlet() 30 | ) 31 | 32 | Home <- div( 33 | tags$h2("Home") 34 | ) 35 | 36 | About <- div( 37 | tags$h2("About") 38 | ) 39 | 40 | Dashboard <- div( 41 | tags$h2("Dashboard") 42 | ) 43 | 44 | NoMatch <- div( 45 | tags$h2("Nothing to see here!"), 46 | tags$p( 47 | Link(to = "/", "Go to the home page") 48 | ) 49 | ) 50 | 51 | ui <- reactRouter::HashRouter( 52 | div( 53 | h1("Basic Example"), 54 | tags$p( 55 | paste0('This example demonstrates some of the core features of React Router 56 | including nested reactRouter::Route(), reactRouter::Outlet(), 57 | reactRouter::Link(), and using a "*" route (aka "splat route") 58 | to render a "not found" page when someone visits an unrecognized URL.' 59 | ) 60 | ), 61 | reactRouter::Routes( 62 | Route( 63 | path = "/", 64 | element = Layout, 65 | Route( 66 | index = TRUE, 67 | element = Home 68 | ), 69 | Route( 70 | path = "about", 71 | element = About 72 | ), 73 | Route( 74 | path = "dashboard", 75 | element = Dashboard 76 | ), 77 | # Using path="*"" means "match anything", so this route 78 | # acts like a catch-all for URLs that we don't have explicit 79 | # routes for. 80 | Route( 81 | path = "*", 82 | element = NoMatch 83 | ) 84 | ) 85 | ) 86 | ) 87 | ) 88 | 89 | server <- function(input, output, session) { } 90 | 91 | if (interactive()) { 92 | shinyApp(ui = ui, server = server) 93 | } 94 | -------------------------------------------------------------------------------- /inst/examples/bslib/app.R: -------------------------------------------------------------------------------- 1 | library(reactRouter) 2 | library(bslib) 3 | library(htmltools) 4 | library(shiny) 5 | 6 | ui <- reactRouter::HashRouter( 7 | bslib::page_navbar( 8 | title = "reactRouter with bslib", 9 | nav_item( 10 | reactRouter::NavLink( 11 | "Home", 12 | to = "/", 13 | style = JS('({isActive}) => { return isActive ? {color: "red", textDecoration: "none"} : {}; }') 14 | ) 15 | ), 16 | nav_item( 17 | reactRouter::NavLink( 18 | "Analysis", 19 | to = "/analysis", 20 | style = JS('({isActive}) => { return isActive ? {color: "red", textDecoration: "none"} : {}; }') 21 | ) 22 | ), 23 | reactRouter::Routes( 24 | reactRouter::Route( 25 | path = "/", 26 | element = div( 27 | tags$h3("Home page"), 28 | p("A basic example of reactRouter with bslib.") 29 | ) 30 | ), 31 | reactRouter::Route( 32 | path = "/analysis", 33 | element = "Content analysis" 34 | ), 35 | reactRouter::Route(path = "*", element = "Custom error 404") 36 | ) 37 | ) 38 | ) 39 | 40 | server <- function(input, output, session) {} 41 | 42 | shinyApp(ui, server) 43 | -------------------------------------------------------------------------------- /inst/examples/dynamic-segment/app.R: -------------------------------------------------------------------------------- 1 | # reactRouter with route parameters 2 | 3 | library(shiny) 4 | library(reactRouter) 5 | library(bslib) 6 | library(dplyr) 7 | library(tidyr) 8 | library(stringr) 9 | 10 | # create list of nested datasets by id 11 | data_nested_by_id <- dplyr::starwars |> 12 | tidyr::unnest_longer(col = films) |> 13 | dplyr::nest_by(films) |> 14 | rename(title = films) |> 15 | mutate(id = case_match( 16 | title, 17 | "A New Hope" ~ 1, 18 | "The Empire Strikes Back" ~ 2, 19 | "Return of the Jedi" ~ 3, 20 | "The Phantom Menace" ~ 4, 21 | "Attack of the Clones" ~ 5, 22 | "Revenge of the Sith" ~ 6, 23 | "The Force Awakens" ~ 7) 24 | ) |> 25 | arrange(id) 26 | 27 | # image URLs for cards 28 | img_by_id <- tibble::tribble( 29 | ~id, ~img, 30 | 1, "https://upload.wikimedia.org/wikipedia/en/8/87/StarWarsMoviePoster1977.jpg", 31 | 2, "https://upload.wikimedia.org/wikipedia/en/3/3f/The_Empire_Strikes_Back_%281980_film%29.jpg", 32 | 3, "https://upload.wikimedia.org/wikipedia/en/b/b2/ReturnOfTheJediPoster1983.jpg", 33 | 4, "https://upload.wikimedia.org/wikipedia/en/4/40/Star_Wars_Phantom_Menace_poster.jpg", 34 | 5, "https://upload.wikimedia.org/wikipedia/en/3/32/Star_Wars_-_Episode_II_Attack_of_the_Clones_%28movie_poster%29.jpg", 35 | 6, "https://upload.wikimedia.org/wikipedia/en/9/93/Star_Wars_Episode_III_Revenge_of_the_Sith_poster.jpg", 36 | 7, "https://upload.wikimedia.org/wikipedia/en/a/a2/Star_Wars_The_Force_Awakens_Theatrical_Poster.jpg" 37 | ) 38 | 39 | create_card <- function(id) { 40 | a( 41 | href = paste0("#/project/", id, "/overview"), 42 | style = "text-decoration: none", 43 | card( 44 | card_body( 45 | class = "p-0", 46 | card_image( 47 | img_by_id$img[id] 48 | ) 49 | ), 50 | card_footer( 51 | data_nested_by_id$title[id] 52 | ) 53 | ) 54 | ) 55 | } 56 | 57 | cards_home <- purrr::map( 58 | .x = data_nested_by_id$id, 59 | .f = create_card 60 | ) 61 | 62 | ui <- reactRouter::HashRouter( 63 | bslib::page_navbar( 64 | window_title = "reactRouter | dynamic segments", 65 | title = span( 66 | reactRouter::Link( 67 | to = "/", 68 | "reactRouter with dynamic segments", 69 | style = "text-decoration: none; color: black" 70 | ) 71 | ), 72 | nav_spacer(), 73 | nav_item( 74 | tags$a( 75 | shiny::icon("code"), 76 | href = "https://github.com/lgnbhl/reactRouter/tree/main/inst/examples" 77 | ) 78 | ), 79 | reactRouter::Routes( 80 | reactRouter::Route( 81 | path = "/", 82 | element = div( 83 | class = "p-2", 84 | uiOutput("uiHome") 85 | ) 86 | ), 87 | reactRouter::Route( 88 | path = "project/:id", 89 | element = bslib::page_navbar( 90 | nav_item( 91 | NavLink( 92 | to = "overview", 93 | "Overview" 94 | ) 95 | ), 96 | nav_item( 97 | NavLink( 98 | to = "analysis", 99 | "Analysis" 100 | ) 101 | ), 102 | bslib::nav_spacer(), 103 | nav_item( 104 | NavLink( 105 | to = "/", 106 | shiny::icon("home") 107 | ) 108 | ), 109 | Outlet() 110 | ), 111 | children = list( 112 | reactRouter::Route( 113 | path = "overview", 114 | element = uiOutput("uiOverview") 115 | ), 116 | reactRouter::Route( 117 | path = "analysis", 118 | element = uiOutput("uiAnalysis") 119 | ) 120 | ) 121 | ) 122 | ) 123 | ) 124 | ) 125 | 126 | server <- function(input, output, session) { 127 | 128 | url_hash <- shiny::reactiveVal(value = NA) 129 | url_hash_cleaned <- shiny::reactiveVal(value = NA) 130 | 131 | # update reactive values based on url hash 132 | shiny::observe({ 133 | current_url_hash <- sub("#/", "", session$clientData$url_hash) 134 | # print(current_url_hash) 135 | url_hash(current_url_hash) 136 | 137 | # extract numeric id from current url hash 138 | current_url_hash_cleaned <- as.integer(stringr::str_extract(current_url_hash, "\\d+")) 139 | # print(current_url_hash_cleaned) 140 | url_hash_cleaned(current_url_hash_cleaned) 141 | }) 142 | 143 | output$uiHome <- shiny::renderUI({ 144 | bslib::layout_column_wrap( 145 | width = 1/7, 146 | !!!unname(cards_home) 147 | ) 148 | }) 149 | 150 | data <- reactive({ 151 | req(url_hash_cleaned()) 152 | # get nested data 153 | data_selected <- data_nested_by_id$data[[url_hash_cleaned()]] 154 | 155 | species <- data_selected |> 156 | count(species, sort = TRUE) |> 157 | na.omit() |> 158 | pull(species) 159 | 160 | oldest <- data_selected |> 161 | arrange(desc(birth_year)) |> 162 | head(1) 163 | 164 | tallest <- data_selected |> 165 | arrange(desc(height)) |> 166 | head(1) 167 | 168 | lightest <- data_selected |> 169 | arrange(mass) |> 170 | head(1) 171 | 172 | tibble( 173 | indicator = c("Species", "Oldest", "Tallest", "Lightest"), 174 | value = c(length(species), oldest$birth_year, tallest$height, lightest$height), 175 | desc = c(paste(species, collapse = ", "), oldest$name, tallest$name, lightest$name) 176 | ) 177 | }) 178 | 179 | output$uiOverview <- renderUI({ 180 | layout_column_wrap( 181 | width = 1/2, 182 | class = "p-3", 183 | card( 184 | card_header("Session and data"), 185 | tags$p( 186 | tags$b("Current hash url: "), 187 | paste0("'", url_hash(), "'") 188 | ), 189 | tags$p( 190 | tags$b("Current cleaned hash url: "), 191 | paste0("'", url_hash_cleaned(), "'") 192 | ), 193 | tags$p( 194 | tags$b(tags$code("title"), "of the data: "), 195 | paste0("'", data_nested_by_id$title[url_hash_cleaned()], "'") 196 | ), 197 | tags$p( 198 | tags$b(tags$code("id"), "of the data: "), 199 | paste0("'", data_nested_by_id$id[url_hash_cleaned()], "'") 200 | ) 201 | ), 202 | layout_column_wrap( 203 | width = 1/2, 204 | heights_equal = "row", 205 | value_box( 206 | title = "Species", 207 | showcase = shiny::icon("users"), 208 | value = filter(data(), indicator == "Species")$value, 209 | shiny::markdown(filter(data(), indicator == "Species")$desc) 210 | ), 211 | value_box( 212 | title = "Oldest", 213 | showcase = shiny::icon("person-cane"), 214 | value = filter(data(), indicator == "Oldest")$value, 215 | shiny::markdown(filter(data(), indicator == "Oldest")$desc) 216 | ), 217 | value_box( 218 | title = "Tallest", 219 | showcase = shiny::icon("up-long"), 220 | value = filter(data(), indicator == "Tallest")$value, 221 | shiny::markdown(filter(data(), indicator == "Tallest")$desc) 222 | ), 223 | value_box( 224 | title = "Lightest", 225 | showcase = shiny::icon("feather"), 226 | value = filter(data(), indicator == "Lightest")$value, 227 | shiny::markdown(filter(data(), indicator == "Lightest")$desc) 228 | ) 229 | ) 230 | ) 231 | }) 232 | 233 | output$uiAnalysis <- renderUI({ 234 | layout_column_wrap( 235 | width = 1/2, 236 | class = "p-3", 237 | card( 238 | card_header("Session and data"), 239 | tags$p( 240 | tags$b("Current hash url: "), 241 | paste0("'", url_hash(), "'") 242 | ), 243 | tags$p( 244 | tags$b("Current cleaned hash url: "), 245 | paste0("'", url_hash_cleaned(), "'") 246 | ) 247 | ), 248 | card( 249 | card_header("Package documentation"), 250 | card_body(shiny::markdown("Learn more about **reactRouter** [here](https://felixluginbuhl.com/reactRouter/).")) 251 | ) 252 | ) 253 | }) 254 | 255 | } 256 | 257 | shinyApp(ui, server) 258 | -------------------------------------------------------------------------------- /inst/reactRouter-6.30.0/react-router-dom.js: -------------------------------------------------------------------------------- 1 | /*! For license information please see react-router-dom.js.LICENSE.txt */ 2 | (()=>{"use strict";var e={111:(e,t,r)=>{r.r(t),r.d(t,{AbortedDeferredError:()=>Y,Await:()=>nr,BrowserRouter:()=>Nr,Form:()=>$r,HashRouter:()=>Br,Link:()=>Wr,MemoryRouter:()=>Gt,NavLink:()=>Kr,Navigate:()=>Qt,NavigationType:()=>i,Outlet:()=>Zt,Route:()=>er,Router:()=>tr,RouterProvider:()=>jr,Routes:()=>rr,ScrollRestoration:()=>Vr,UNSAFE_DataRouterContext:()=>at,UNSAFE_DataRouterStateContext:()=>ot,UNSAFE_ErrorResponseImpl:()=>re,UNSAFE_FetchersContext:()=>kr,UNSAFE_LocationContext:()=>lt,UNSAFE_NavigationContext:()=>st,UNSAFE_RouteContext:()=>ut,UNSAFE_ViewTransitionContext:()=>Lr,UNSAFE_useRouteId:()=>jt,UNSAFE_useScrollRestoration:()=>ln,createBrowserRouter:()=>xr,createHashRouter:()=>Dr,createMemoryRouter:()=>dr,createPath:()=>m,createRoutesFromChildren:()=>lr,createRoutesFromElements:()=>lr,createSearchParams:()=>yr,defer:()=>Q,generatePath:()=>j,isRouteErrorResponse:()=>ne,json:()=>q,matchPath:()=>O,matchRoutes:()=>S,parsePath:()=>v,redirect:()=>Z,redirectDocument:()=>ee,renderMatches:()=>ur,replace:()=>te,resolvePath:()=>B,unstable_HistoryRouter:()=>Ir,unstable_usePrompt:()=>cn,useActionData:()=>zt,useAsyncError:()=>Kt,useAsyncValue:()=>Wt,useBeforeUnload:()=>un,useBlocker:()=>Vt,useFetcher:()=>nn,useFetchers:()=>an,useFormAction:()=>rn,useHref:()=>dt,useInRouterContext:()=>ht,useLinkClickHandler:()=>Gr,useLoaderData:()=>Bt,useLocation:()=>ft,useMatch:()=>mt,useMatches:()=>Nt,useNavigate:()=>yt,useNavigation:()=>Ot,useNavigationType:()=>pt,useOutlet:()=>wt,useOutletContext:()=>bt,useParams:()=>St,useResolvedPath:()=>Et,useRevalidator:()=>Ft,useRouteError:()=>Ht,useRouteLoaderData:()=>It,useRoutes:()=>Rt,useSearchParams:()=>Qr,useSubmit:()=>tn,useViewTransitionState:()=>dn});const n=jsmodule.react,a=jsmodule["react-dom"];function o(){return o=Object.assign?Object.assign.bind():function(e){for(var t=1;td(e,"string"==typeof e?null:e.state,0===t?"default":void 0)));let o=u(null==n?t.length-1:n),s=i.Pop,l=null;function u(e){return Math.min(Math.max(e,0),t.length-1)}function c(){return t[o]}function d(e,r,n){void 0===r&&(r=null);let a=p(t?c().pathname:"/",e,r,n);return h("/"===a.pathname.charAt(0),"relative pathnames are not supported in memory history: "+JSON.stringify(e)),a}function f(e){return"string"==typeof e?e:m(e)}return{get index(){return o},get action(){return s},get location(){return c()},createHref:f,createURL:e=>new URL(f(e),"http://localhost"),encodeLocation(e){let t="string"==typeof e?v(e):e;return{pathname:t.pathname||"",search:t.search||"",hash:t.hash||""}},push(e,r){s=i.Push;let n=d(e,r);o+=1,t.splice(o,t.length,n),a&&l&&l({action:s,location:n,delta:1})},replace(e,r){s=i.Replace;let n=d(e,r);t[o]=n,a&&l&&l({action:s,location:n,delta:0})},go(e){s=i.Pop;let r=u(o+e),n=t[r];o=r,l&&l({action:s,location:n,delta:e})},listen:e=>(l=e,()=>{l=null})}}function u(e){return void 0===e&&(e={}),y((function(e,t){let{pathname:r,search:n,hash:a}=e.location;return p("",{pathname:r,search:n,hash:a},t.state&&t.state.usr||null,t.state&&t.state.key||"default")}),(function(e,t){return"string"==typeof t?t:m(t)}),null,e)}function c(e){return void 0===e&&(e={}),y((function(e,t){let{pathname:r="/",search:n="",hash:a=""}=v(e.location.hash.substr(1));return r.startsWith("/")||r.startsWith(".")||(r="/"+r),p("",{pathname:r,search:n,hash:a},t.state&&t.state.usr||null,t.state&&t.state.key||"default")}),(function(e,t){let r=e.document.querySelector("base"),n="";if(r&&r.getAttribute("href")){let t=e.location.href,r=t.indexOf("#");n=-1===r?t:t.slice(0,r)}return n+"#"+("string"==typeof t?t:m(t))}),(function(e,t){h("/"===e.pathname.charAt(0),"relative pathnames are not supported in hash history.push("+JSON.stringify(t)+")")}),e)}function d(e,t){if(!1===e||null==e)throw new Error(t)}function h(e,t){if(!e){"undefined"!=typeof console&&console.warn(t);try{throw new Error(t)}catch(e){}}}function f(e,t){return{usr:e.state,key:e.key,idx:t}}function p(e,t,r,n){return void 0===r&&(r=null),o({pathname:"string"==typeof e?e:e.pathname,search:"",hash:""},"string"==typeof t?v(t):t,{state:r,key:t&&t.key||n||Math.random().toString(36).substr(2,8)})}function m(e){let{pathname:t="/",search:r="",hash:n=""}=e;return r&&"?"!==r&&(t+="?"===r.charAt(0)?r:"?"+r),n&&"#"!==n&&(t+="#"===n.charAt(0)?n:"#"+n),t}function v(e){let t={};if(e){let r=e.indexOf("#");r>=0&&(t.hash=e.substr(r),e=e.substr(0,r));let n=e.indexOf("?");n>=0&&(t.search=e.substr(n),e=e.substr(0,n)),e&&(t.pathname=e)}return t}function y(e,t,r,n){void 0===n&&(n={});let{window:a=document.defaultView,v5Compat:l=!1}=n,u=a.history,c=i.Pop,h=null,v=y();function y(){return(u.state||{idx:null}).idx}function g(){c=i.Pop;let e=y(),t=null==e?null:e-v;v=e,h&&h({action:c,location:w.location,delta:t})}function b(e){let t="null"!==a.location.origin?a.location.origin:a.location.href,r="string"==typeof e?e:m(e);return r=r.replace(/ $/,"%20"),d(t,"No window.location.(origin|href) available to create URL for href: "+r),new URL(r,t)}null==v&&(v=0,u.replaceState(o({},u.state,{idx:v}),""));let w={get action(){return c},get location(){return e(a,u)},listen(e){if(h)throw new Error("A history only accepts one active listener");return a.addEventListener(s,g),h=e,()=>{a.removeEventListener(s,g),h=null}},createHref:e=>t(a,e),createURL:b,encodeLocation(e){let t=b(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:function(e,t){c=i.Push;let n=p(w.location,e,t);r&&r(n,e),v=y()+1;let o=f(n,v),s=w.createHref(n);try{u.pushState(o,"",s)}catch(e){if(e instanceof DOMException&&"DataCloneError"===e.name)throw e;a.location.assign(s)}l&&h&&h({action:c,location:w.location,delta:1})},replace:function(e,t){c=i.Replace;let n=p(w.location,e,t);r&&r(n,e),v=y();let a=f(n,v),o=w.createHref(n);u.replaceState(a,"",o),l&&h&&h({action:c,location:w.location,delta:0})},go:e=>u.go(e)};return w}var g;!function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"}(g||(g={}));const b=new Set(["lazy","caseSensitive","path","id","index","children"]);function w(e,t,r,n){return void 0===r&&(r=[]),void 0===n&&(n={}),e.map(((e,a)=>{let i=[...r,String(a)],s="string"==typeof e.id?e.id:i.join("-");if(d(!0!==e.index||!e.children,"Cannot specify children on an index route"),d(!n[s],'Found a route id collision on id "'+s+"\". Route id's must be globally unique within Data Router usages"),function(e){return!0===e.index}(e)){let r=o({},e,t(e),{id:s});return n[s]=r,r}{let r=o({},e,t(e),{id:s,children:void 0});return n[s]=r,e.children&&(r.children=w(e.children,t,i,n)),r}}))}function S(e,t,r){return void 0===r&&(r="/"),E(e,t,r,!1)}function E(e,t,r,n){let a=N(("string"==typeof t?v(t):t).pathname||"/",r);if(null==a)return null;let o=x(e);!function(e){e.sort(((e,t)=>e.score!==t.score?t.score-e.score:function(e,t){return e.length===t.length&&e.slice(0,-1).every(((e,r)=>e===t[r]))?e[e.length-1]-t[t.length-1]:0}(e.routesMeta.map((e=>e.childrenIndex)),t.routesMeta.map((e=>e.childrenIndex)))))}(o);let i=null;for(let e=0;null==i&&e{let i={relativePath:void 0===o?e.path||"":o,caseSensitive:!0===e.caseSensitive,childrenIndex:a,route:e};i.relativePath.startsWith("/")&&(d(i.relativePath.startsWith(n),'Absolute route path "'+i.relativePath+'" nested under path "'+n+'" is not valid. An absolute child route path must start with the combined path of all its parent routes.'),i.relativePath=i.relativePath.slice(n.length));let s=K([n,i.relativePath]),l=r.concat(i);e.children&&e.children.length>0&&(d(!0!==e.index,'Index routes must not have child routes. Please remove all child routes from route path "'+s+'".'),x(e.children,t,l,s)),(null!=e.path||e.index)&&t.push({path:s,score:M(s,e.index),routesMeta:l})};return e.forEach(((e,t)=>{var r;if(""!==e.path&&null!=(r=e.path)&&r.includes("?"))for(let r of D(e.path))a(e,t,r);else a(e,t)})),t}function D(e){let t=e.split("/");if(0===t.length)return[];let[r,...n]=t,a=r.endsWith("?"),o=r.replace(/\?$/,"");if(0===n.length)return a?[o,""]:[o];let i=D(n.join("/")),s=[];return s.push(...i.map((e=>""===e?o:[o,e].join("/")))),a&&s.push(...i),s.map((t=>e.startsWith("/")&&""===t?"/":t))}const C=/^:[\w-]+$/,P=3,L=2,k=1,T=10,_=-2,A=e=>"*"===e;function M(e,t){let r=e.split("/"),n=r.length;return r.some(A)&&(n+=_),t&&(n+=L),r.filter((e=>!A(e))).reduce(((e,t)=>e+(C.test(t)?P:""===t?k:T)),n)}function U(e,t,r){void 0===r&&(r=!1);let{routesMeta:n}=e,a={},o="/",i=[];for(let e=0;enull==e?"":"string"==typeof e?e:String(e);return n+r.split(/\/+/).map(((e,r,n)=>{if(r===n.length-1&&"*"===e)return a(t["*"]);const o=e.match(/^:([\w-]+)(\??)$/);if(o){const[,e,r]=o;let n=t[e];return d("?"===r||null!=n,'Missing ":'+e+'" param'),a(n)}return e.replace(/\?$/g,"")})).filter((e=>!!e)).join("/")}function O(e,t){"string"==typeof e&&(e={path:e,caseSensitive:!1,end:!0});let[r,n]=function(e,t,r){void 0===t&&(t=!1),void 0===r&&(r=!0),h("*"===e||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were "'+e.replace(/\*$/,"/*")+'" because the `*` character must always follow a `/` in the pattern. To get rid of this warning, please change the route path to "'+e.replace(/\*$/,"/*")+'".');let n=[],a="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,((e,t,r)=>(n.push({paramName:t,isOptional:null!=r}),r?"/?([^\\/]+)?":"/([^\\/]+)")));return e.endsWith("*")?(n.push({paramName:"*"}),a+="*"===e||"/*"===e?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?a+="\\/*$":""!==e&&"/"!==e&&(a+="(?:(?=\\/|$))"),[new RegExp(a,t?void 0:"i"),n]}(e.path,e.caseSensitive,e.end),a=t.match(r);if(!a)return null;let o=a[0],i=o.replace(/(.)\/+$/,"$1"),s=a.slice(1);return{params:n.reduce(((e,t,r)=>{let{paramName:n,isOptional:a}=t;if("*"===n){let e=s[r]||"";i=o.slice(0,o.length-e.length).replace(/(.)\/+$/,"$1")}const l=s[r];return e[n]=a&&!l?void 0:(l||"").replace(/%2F/g,"/"),e}),{}),pathname:o,pathnameBase:i,pattern:e}}function F(e){try{return e.split("/").map((e=>decodeURIComponent(e).replace(/\//g,"%2F"))).join("/")}catch(t){return h(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent encoding ('+t+")."),e}}function N(e,t){if("/"===t)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let r=t.endsWith("/")?t.length-1:t.length,n=e.charAt(r);return n&&"/"!==n?null:e.slice(r)||"/"}function B(e,t){void 0===t&&(t="/");let{pathname:r,search:n="",hash:a=""}="string"==typeof e?v(e):e,o=r?r.startsWith("/")?r:function(e,t){let r=t.replace(/\/+$/,"").split("/");return e.split("/").forEach((e=>{".."===e?r.length>1&&r.pop():"."!==e&&r.push(e)})),r.length>1?r.join("/"):"/"}(r,t):t;return{pathname:o,search:V(n),hash:J(a)}}function I(e,t,r,n){return"Cannot include a '"+e+"' character in a manually specified `to."+t+"` field ["+JSON.stringify(n)+"]. Please separate it out to the `to."+r+'` field. Alternatively you may provide the full path as a string in and the router will parse it for you.'}function z(e){return e.filter(((e,t)=>0===t||e.route.path&&e.route.path.length>0))}function H(e,t){let r=z(e);return t?r.map(((e,t)=>t===r.length-1?e.pathname:e.pathnameBase)):r.map((e=>e.pathnameBase))}function W(e,t,r,n){let a;void 0===n&&(n=!1),"string"==typeof e?a=v(e):(a=o({},e),d(!a.pathname||!a.pathname.includes("?"),I("?","pathname","search",a)),d(!a.pathname||!a.pathname.includes("#"),I("#","pathname","hash",a)),d(!a.search||!a.search.includes("#"),I("#","search","hash",a)));let i,s=""===e||""===a.pathname,l=s?"/":a.pathname;if(null==l)i=r;else{let e=t.length-1;if(!n&&l.startsWith("..")){let t=l.split("/");for(;".."===t[0];)t.shift(),e-=1;a.pathname=t.join("/")}i=e>=0?t[e]:"/"}let u=B(a,i),c=l&&"/"!==l&&l.endsWith("/"),h=(s||"."===l)&&r.endsWith("/");return u.pathname.endsWith("/")||!c&&!h||(u.pathname+="/"),u}const K=e=>e.join("/").replace(/\/\/+/g,"/"),$=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),V=e=>e&&"?"!==e?e.startsWith("?")?e:"?"+e:"",J=e=>e&&"#"!==e?e.startsWith("#")?e:"#"+e:"",q=function(e,t){void 0===t&&(t={});let r="number"==typeof t?{status:t}:t,n=new Headers(r.headers);return n.has("Content-Type")||n.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(e),o({},r,{headers:n}))};class Y extends Error{}class X{constructor(e,t){let r;this.pendingKeysSet=new Set,this.subscribers=new Set,this.deferredKeys=[],d(e&&"object"==typeof e&&!Array.isArray(e),"defer() only accepts plain objects"),this.abortPromise=new Promise(((e,t)=>r=t)),this.controller=new AbortController;let n=()=>r(new Y("Deferred data aborted"));this.unlistenAbortSignal=()=>this.controller.signal.removeEventListener("abort",n),this.controller.signal.addEventListener("abort",n),this.data=Object.entries(e).reduce(((e,t)=>{let[r,n]=t;return Object.assign(e,{[r]:this.trackPromise(r,n)})}),{}),this.done&&this.unlistenAbortSignal(),this.init=t}trackPromise(e,t){if(!(t instanceof Promise))return t;this.deferredKeys.push(e),this.pendingKeysSet.add(e);let r=Promise.race([t,this.abortPromise]).then((t=>this.onSettle(r,e,void 0,t)),(t=>this.onSettle(r,e,t)));return r.catch((()=>{})),Object.defineProperty(r,"_tracked",{get:()=>!0}),r}onSettle(e,t,r,n){if(this.controller.signal.aborted&&r instanceof Y)return this.unlistenAbortSignal(),Object.defineProperty(e,"_error",{get:()=>r}),Promise.reject(r);if(this.pendingKeysSet.delete(t),this.done&&this.unlistenAbortSignal(),void 0===r&&void 0===n){let r=new Error('Deferred data for key "'+t+'" resolved/rejected with `undefined`, you must resolve/reject with a value or `null`.');return Object.defineProperty(e,"_error",{get:()=>r}),this.emit(!1,t),Promise.reject(r)}return void 0===n?(Object.defineProperty(e,"_error",{get:()=>r}),this.emit(!1,t),Promise.reject(r)):(Object.defineProperty(e,"_data",{get:()=>n}),this.emit(!1,t),n)}emit(e,t){this.subscribers.forEach((r=>r(e,t)))}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}cancel(){this.controller.abort(),this.pendingKeysSet.forEach(((e,t)=>this.pendingKeysSet.delete(t))),this.emit(!0)}async resolveData(e){let t=!1;if(!this.done){let r=()=>this.cancel();e.addEventListener("abort",r),t=await new Promise((t=>{this.subscribe((n=>{e.removeEventListener("abort",r),(n||this.done)&&t(n)}))}))}return t}get done(){return 0===this.pendingKeysSet.size}get unwrappedData(){return d(null!==this.data&&this.done,"Can only unwrap data on initialized and settled deferreds"),Object.entries(this.data).reduce(((e,t)=>{let[r,n]=t;return Object.assign(e,{[r]:G(n)})}),{})}get pendingKeys(){return Array.from(this.pendingKeysSet)}}function G(e){if(!function(e){return e instanceof Promise&&!0===e._tracked}(e))return e;if(e._error)throw e._error;return e._data}const Q=function(e,t){return void 0===t&&(t={}),new X(e,"number"==typeof t?{status:t}:t)},Z=function(e,t){void 0===t&&(t=302);let r=t;"number"==typeof r?r={status:r}:void 0===r.status&&(r.status=302);let n=new Headers(r.headers);return n.set("Location",e),new Response(null,o({},r,{headers:n}))},ee=(e,t)=>{let r=Z(e,t);return r.headers.set("X-Remix-Reload-Document","true"),r},te=(e,t)=>{let r=Z(e,t);return r.headers.set("X-Remix-Replace","true"),r};class re{constructor(e,t,r,n){void 0===n&&(n=!1),this.status=e,this.statusText=t||"",this.internal=n,r instanceof Error?(this.data=r.toString(),this.error=r):this.data=r}}function ne(e){return null!=e&&"number"==typeof e.status&&"string"==typeof e.statusText&&"boolean"==typeof e.internal&&"data"in e}const ae=["post","put","patch","delete"],oe=new Set(ae),ie=["get",...ae],se=new Set(ie),le=new Set([301,302,303,307,308]),ue=new Set([307,308]),ce={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},de={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},he={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},fe=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,pe=e=>({hasErrorBoundary:Boolean(e.hasErrorBoundary)}),me="remix-router-transitions";function ve(e){const t=e.window?e.window:"undefined"!=typeof window?window:void 0,r=void 0!==t&&void 0!==t.document&&void 0!==t.document.createElement,n=!r;let a;if(d(e.routes.length>0,"You must provide a non-empty routes array to createRouter"),e.mapRouteProperties)a=e.mapRouteProperties;else if(e.detectErrorBoundary){let t=e.detectErrorBoundary;a=e=>({hasErrorBoundary:t(e)})}else a=pe;let s,l,u,c={},f=w(e.routes,a,void 0,c),m=e.basename||"/",v=e.dataStrategy||Ce,y=e.patchRoutesOnNavigation,x=o({v7_fetcherPersist:!1,v7_normalizeFormMethod:!1,v7_partialHydration:!1,v7_prependBasename:!1,v7_relativeSplatPath:!1,v7_skipActionErrorRevalidation:!1},e.future),D=null,C=new Set,P=null,L=null,k=null,T=null!=e.hydrationData,_=S(f,e.history.location,m),A=!1,M=null;if(null==_&&!y){let t=Ne(404,{pathname:e.history.location.pathname}),{matches:r,route:n}=Fe(f);_=r,M={[n.id]:t}}if(_&&!e.hydrationData&&ct(_,f,e.history.location.pathname).active&&(_=null),_)if(_.some((e=>e.route.lazy)))l=!1;else if(_.some((e=>e.route.loader)))if(x.v7_partialHydration){let t=e.hydrationData?e.hydrationData.loaderData:null,r=e.hydrationData?e.hydrationData.errors:null;if(r){let e=_.findIndex((e=>void 0!==r[e.route.id]));l=_.slice(0,e+1).every((e=>!Se(e.route,t,r)))}else l=_.every((e=>!Se(e.route,t,r)))}else l=null!=e.hydrationData;else l=!0;else if(l=!1,_=[],x.v7_partialHydration){let t=ct(null,f,e.history.location.pathname);t.active&&t.matches&&(A=!0,_=t.matches)}let U,j,O={historyAction:e.history.action,location:e.history.location,matches:_,initialized:l,navigation:ce,restoreScrollPosition:null==e.hydrationData&&null,preventScrollReset:!1,revalidation:"idle",loaderData:e.hydrationData&&e.hydrationData.loaderData||{},actionData:e.hydrationData&&e.hydrationData.actionData||null,errors:e.hydrationData&&e.hydrationData.errors||M,fetchers:new Map,blockers:new Map},F=i.Pop,B=!1,I=!1,z=new Map,H=null,W=!1,K=!1,$=[],V=new Set,J=new Map,q=0,Y=-1,X=new Map,G=new Set,Q=new Map,Z=new Map,ee=new Set,te=new Map,re=new Map;function ae(e,t){void 0===t&&(t={}),O=o({},O,e);let r=[],n=[];x.v7_fetcherPersist&&O.fetchers.forEach(((e,t)=>{"idle"===e.state&&(ee.has(t)?n.push(t):r.push(t))})),ee.forEach((e=>{O.fetchers.has(e)||J.has(e)||n.push(e)})),[...C].forEach((e=>e(O,{deletedFetchers:n,viewTransitionOpts:t.viewTransitionOpts,flushSync:!0===t.flushSync}))),x.v7_fetcherPersist?(r.forEach((e=>O.fetchers.delete(e))),n.forEach((e=>Ae(e)))):n.forEach((e=>ee.delete(e)))}function oe(t,r,n){var a,l;let u,{flushSync:c}=void 0===n?{}:n,d=null!=O.actionData&&null!=O.navigation.formMethod&&Je(O.navigation.formMethod)&&"loading"===O.navigation.state&&!0!==(null==(a=t.state)?void 0:a._isRedirect);u=r.actionData?Object.keys(r.actionData).length>0?r.actionData:null:d?O.actionData:null;let h=r.loaderData?Ue(O.loaderData,r.loaderData,r.matches||[],r.errors):O.loaderData,p=O.blockers;p.size>0&&(p=new Map(p),p.forEach(((e,t)=>p.set(t,he))));let m,v=!0===B||null!=O.navigation.formMethod&&Je(O.navigation.formMethod)&&!0!==(null==(l=t.state)?void 0:l._isRedirect);if(s&&(f=s,s=void 0),W||F===i.Pop||(F===i.Push?e.history.push(t,t.state):F===i.Replace&&e.history.replace(t,t.state)),F===i.Pop){let e=z.get(O.location.pathname);e&&e.has(t.pathname)?m={currentLocation:O.location,nextLocation:t}:z.has(t.pathname)&&(m={currentLocation:t,nextLocation:O.location})}else if(I){let e=z.get(O.location.pathname);e?e.add(t.pathname):(e=new Set([t.pathname]),z.set(O.location.pathname,e)),m={currentLocation:O.location,nextLocation:t}}ae(o({},r,{actionData:u,loaderData:h,historyAction:F,location:t,initialized:!0,navigation:ce,revalidation:"idle",restoreScrollPosition:ut(t,r.matches||O.matches),preventScrollReset:v,blockers:p}),{viewTransitionOpts:m,flushSync:!0===c}),F=i.Pop,B=!1,I=!1,W=!1,K=!1,$=[]}async function ie(t,r,n){U&&U.abort(),U=null,F=t,W=!0===(n&&n.startUninterruptedRevalidation),function(e,t){if(P&&k){let r=lt(e,t);P[r]=k()}}(O.location,O.matches),B=!0===(n&&n.preventScrollReset),I=!0===(n&&n.enableViewTransition);let a=s||f,l=n&&n.overrideNavigation,u=null!=n&&n.initialHydration&&O.matches&&O.matches.length>0&&!A?O.matches:S(a,r,m),c=!0===(n&&n.flushSync);if(u&&O.initialized&&!K&&(d=O.location,h=r,d.pathname===h.pathname&&d.search===h.search&&(""===d.hash?""!==h.hash:d.hash===h.hash||""!==h.hash))&&!(n&&n.submission&&Je(n.submission.formMethod)))return void oe(r,{matches:u},{flushSync:c});var d,h;let p=ct(u,a,r.pathname);if(p.active&&p.matches&&(u=p.matches),!u){let{error:e,notFoundMatches:t,route:n}=it(r.pathname);return void oe(r,{matches:t,loaderData:{},errors:{[n.id]:e}},{flushSync:c})}U=new AbortController;let v,y=Te(e.history,r,U.signal,n&&n.submission);if(n&&n.pendingError)v=[Oe(u).route.id,{type:g.error,error:n.pendingError}];else if(n&&n.submission&&Je(n.submission.formMethod)){let t=await async function(e,t,r,n,a,o){void 0===o&&(o={}),Ee();let s,l=function(e,t){return{state:"submitting",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}}(t,r);if(ae({navigation:l},{flushSync:!0===o.flushSync}),a){let r=await dt(n,t.pathname,e.signal);if("aborted"===r.type)return{shortCircuited:!0};if("error"===r.type){let e=Oe(r.partialMatches).route.id;return{matches:r.partialMatches,pendingActionResult:[e,{type:g.error,error:r.error}]}}if(!r.matches){let{notFoundMatches:e,error:r,route:n}=it(t.pathname);return{matches:e,pendingActionResult:[n.id,{type:g.error,error:r}]}}n=r.matches}let u=Qe(n,t);if(u.route.action||u.route.lazy){if(s=(await ve("action",O,e,[u],n,null))[u.route.id],e.signal.aborted)return{shortCircuited:!0}}else s={type:g.error,error:Ne(405,{method:e.method,pathname:t.pathname,routeId:u.route.id})};if(Ke(s)){let t;return t=o&&null!=o.replace?o.replace:ke(s.response.headers.get("Location"),new URL(e.url),m)===O.location.pathname+O.location.search,await le(e,s,!0,{submission:r,replace:t}),{shortCircuited:!0}}if(He(s))throw Ne(400,{type:"defer-action"});if(We(s)){let e=Oe(n,u.route.id);return!0!==(o&&o.replace)&&(F=i.Push),{matches:n,pendingActionResult:[e.route.id,s]}}return{matches:n,pendingActionResult:[u.route.id,s]}}(y,r,n.submission,u,p.active,{replace:n.replace,flushSync:c});if(t.shortCircuited)return;if(t.pendingActionResult){let[e,n]=t.pendingActionResult;if(We(n)&&ne(n.error)&&404===n.error.status)return U=null,void oe(r,{matches:t.matches,loaderData:{},errors:{[e]:n.error}})}u=t.matches||u,v=t.pendingActionResult,l=et(r,n.submission),c=!1,p.active=!1,y=Te(e.history,y.url,y.signal)}let{shortCircuited:b,matches:w,loaderData:E,errors:R}=await async function(t,r,n,a,i,l,u,c,d,h,p){let v=i||et(r,l),y=l||u||Ze(v),g=!(W||x.v7_partialHydration&&d);if(a){if(g){let e=se(p);ae(o({navigation:v},void 0!==e?{actionData:e}:{}),{flushSync:h})}let e=await dt(n,r.pathname,t.signal);if("aborted"===e.type)return{shortCircuited:!0};if("error"===e.type){let t=Oe(e.partialMatches).route.id;return{matches:e.partialMatches,loaderData:{},errors:{[t]:e.error}}}if(!e.matches){let{error:e,notFoundMatches:t,route:n}=it(r.pathname);return{matches:t,loaderData:{},errors:{[n.id]:e}}}n=e.matches}let b=s||f,[w,S]=we(e.history,O,n,y,r,x.v7_partialHydration&&!0===d,x.v7_skipActionErrorRevalidation,K,$,V,ee,Q,G,b,m,p);if(st((e=>!(n&&n.some((t=>t.route.id===e)))||w&&w.some((t=>t.route.id===e)))),Y=++q,0===w.length&&0===S.length){let e=Ve();return oe(r,o({matches:n,loaderData:{},errors:p&&We(p[1])?{[p[0]]:p[1].error}:null},je(p),e?{fetchers:new Map(O.fetchers)}:{}),{flushSync:h}),{shortCircuited:!0}}if(g){let e={};if(!a){e.navigation=v;let t=se(p);void 0!==t&&(e.actionData=t)}S.length>0&&(e.fetchers=function(e){return e.forEach((e=>{let t=O.fetchers.get(e.key),r=tt(void 0,t?t.data:void 0);O.fetchers.set(e.key,r)})),new Map(O.fetchers)}(S)),ae(e,{flushSync:h})}S.forEach((e=>{Ie(e.key),e.controller&&J.set(e.key,e.controller)}));let E=()=>S.forEach((e=>Ie(e.key)));U&&U.signal.addEventListener("abort",E);let{loaderResults:R,fetcherResults:D}=await be(O,n,w,S,t);if(t.signal.aborted)return{shortCircuited:!0};U&&U.signal.removeEventListener("abort",E),S.forEach((e=>J.delete(e.key)));let C=Be(R);if(C)return await le(t,C.result,!0,{replace:c}),{shortCircuited:!0};if(C=Be(D),C)return G.add(C.key),await le(t,C.result,!0,{replace:c}),{shortCircuited:!0};let{loaderData:P,errors:L}=Me(O,n,R,p,S,D,te);te.forEach(((e,t)=>{e.subscribe((r=>{(r||e.done)&&te.delete(t)}))})),x.v7_partialHydration&&d&&O.errors&&(L=o({},O.errors,L));let k=Ve(),T=Ge(Y),_=k||T||S.length>0;return o({matches:n,loaderData:P,errors:L},_?{fetchers:new Map(O.fetchers)}:{})}(y,r,u,p.active,l,n&&n.submission,n&&n.fetcherSubmission,n&&n.replace,n&&!0===n.initialHydration,c,v);b||(U=null,oe(r,o({matches:w||u},je(v),{loaderData:E,errors:R})))}function se(e){return e&&!We(e[1])?{[e[0]]:e[1].data}:O.actionData?0===Object.keys(O.actionData).length?null:O.actionData:void 0}async function le(n,a,s,l){let{submission:u,fetcherSubmission:c,preventScrollReset:h,replace:f}=void 0===l?{}:l;a.response.headers.has("X-Remix-Revalidate")&&(K=!0);let v=a.response.headers.get("Location");d(v,"Expected a Location header on the redirect Response"),v=ke(v,new URL(n.url),m);let y=p(O.location,v,{_isRedirect:!0});if(r){let r=!1;if(a.response.headers.has("X-Remix-Reload-Document"))r=!0;else if(fe.test(v)){const n=e.history.createURL(v);r=n.origin!==t.location.origin||null==N(n.pathname,m)}if(r)return void(f?t.location.replace(v):t.location.assign(v))}U=null;let g=!0===f||a.response.headers.has("X-Remix-Replace")?i.Replace:i.Push,{formMethod:b,formAction:w,formEncType:S}=O.navigation;!u&&!c&&b&&w&&S&&(u=Ze(O.navigation));let E=u||c;if(ue.has(a.response.status)&&E&&Je(E.formMethod))await ie(g,y,{submission:o({},E,{formAction:v}),preventScrollReset:h||B,enableViewTransition:s?I:void 0});else{let e=et(y,u);await ie(g,y,{overrideNavigation:e,fetcherSubmission:c,preventScrollReset:h||B,enableViewTransition:s?I:void 0})}}async function ve(e,t,r,n,i,s){let l,u={};try{l=await async function(e,t,r,n,a,i,s,l,u,c){let f=i.map((e=>e.route.lazy?async function(e,t,r){if(!e.lazy)return;let n=await e.lazy();if(!e.lazy)return;let a=r[e.id];d(a,"No route found in manifest");let i={};for(let e in n){let t=void 0!==a[e]&&"hasErrorBoundary"!==e;h(!t,'Route "'+a.id+'" has a static property "'+e+'" defined but its lazy function is also returning a value for this property. The lazy route property "'+e+'" will be ignored.'),t||b.has(e)||(i[e]=n[e])}Object.assign(a,i),Object.assign(a,o({},t(a),{lazy:void 0}))}(e.route,u,l):void 0)),p=i.map(((e,r)=>{let i=f[r],s=a.some((t=>t.route.id===e.route.id));return o({},e,{shouldLoad:s,resolve:async r=>(r&&"GET"===n.method&&(e.route.lazy||e.route.loader)&&(s=!0),s?async function(e,t,r,n,a,o){let i,s,l=n=>{let i,l=new Promise(((e,t)=>i=t));s=()=>i(),t.signal.addEventListener("abort",s);let u=a=>"function"!=typeof n?Promise.reject(new Error('You cannot call the handler for a route which defines a boolean "'+e+'" [routeId: '+r.route.id+"]")):n({request:t,params:r.params,context:o},...void 0!==a?[a]:[]),c=(async()=>{try{return{type:"data",result:await(a?a((e=>u(e))):u())}}catch(e){return{type:"error",result:e}}})();return Promise.race([c,l])};try{let a=r.route[e];if(n)if(a){let e,[t]=await Promise.all([l(a).catch((t=>{e=t})),n]);if(void 0!==e)throw e;i=t}else{if(await n,a=r.route[e],!a){if("action"===e){let e=new URL(t.url),n=e.pathname+e.search;throw Ne(405,{method:t.method,pathname:n,routeId:r.route.id})}return{type:g.data,result:void 0}}i=await l(a)}else{if(!a){let e=new URL(t.url);throw Ne(404,{pathname:e.pathname+e.search})}i=await l(a)}d(void 0!==i.result,"You defined "+("action"===e?"an action":"a loader")+' for route "'+r.route.id+"\" but didn't return anything from your `"+e+"` function. Please return a value or `null`.")}catch(e){return{type:g.error,result:e}}finally{s&&t.signal.removeEventListener("abort",s)}return i}(t,n,e,i,r,c):Promise.resolve({type:g.data,result:void 0}))})})),m=await e({matches:p,request:n,params:i[0].params,fetcherKey:s,context:c});try{await Promise.all(f)}catch(e){}return m}(v,e,0,r,n,i,s,c,a)}catch(e){return n.forEach((t=>{u[t.route.id]={type:g.error,error:e}})),u}for(let[e,t]of Object.entries(l))if(ze(t)){let n=t.result;u[e]={type:g.redirect,response:Le(n,r,e,i,m,x.v7_relativeSplatPath)}}else u[e]=await Pe(t);return u}async function be(t,r,n,a,o){let i=t.matches,s=ve("loader",0,o,n,r,null),l=Promise.all(a.map((async t=>{if(t.matches&&t.match&&t.controller){let r=(await ve("loader",0,Te(e.history,t.path,t.controller.signal),[t.match],t.matches,t.key))[t.match.route.id];return{[t.key]:r}}return Promise.resolve({[t.key]:{type:g.error,error:Ne(404,{pathname:t.path})}})}))),u=await s,c=(await l).reduce(((e,t)=>Object.assign(e,t)),{});return await Promise.all([qe(r,u,o.signal,i,t.loaderData),Ye(r,c,a)]),{loaderResults:u,fetcherResults:c}}function Ee(){K=!0,$.push(...st()),Q.forEach(((e,t)=>{J.has(t)&&V.add(t),Ie(t)}))}function Re(e,t,r){void 0===r&&(r={}),O.fetchers.set(e,t),ae({fetchers:new Map(O.fetchers)},{flushSync:!0===(r&&r.flushSync)})}function De(e,t,r,n){void 0===n&&(n={});let a=Oe(O.matches,t);Ae(e),ae({errors:{[a.route.id]:r},fetchers:new Map(O.fetchers)},{flushSync:!0===(n&&n.flushSync)})}function _e(e){return Z.set(e,(Z.get(e)||0)+1),ee.has(e)&&ee.delete(e),O.fetchers.get(e)||de}function Ae(e){let t=O.fetchers.get(e);!J.has(e)||t&&"loading"===t.state&&X.has(e)||Ie(e),Q.delete(e),X.delete(e),G.delete(e),x.v7_fetcherPersist&&ee.delete(e),V.delete(e),O.fetchers.delete(e)}function Ie(e){let t=J.get(e);t&&(t.abort(),J.delete(e))}function $e(e){for(let t of e){let e=rt(_e(t).data);O.fetchers.set(t,e)}}function Ve(){let e=[],t=!1;for(let r of G){let n=O.fetchers.get(r);d(n,"Expected fetcher: "+r),"loading"===n.state&&(G.delete(r),e.push(r),t=!0)}return $e(e),t}function Ge(e){let t=[];for(let[r,n]of X)if(n0}function nt(e){O.blockers.delete(e),re.delete(e)}function at(e,t){let r=O.blockers.get(e)||he;d("unblocked"===r.state&&"blocked"===t.state||"blocked"===r.state&&"blocked"===t.state||"blocked"===r.state&&"proceeding"===t.state||"blocked"===r.state&&"unblocked"===t.state||"proceeding"===r.state&&"unblocked"===t.state,"Invalid blocker state transition: "+r.state+" -> "+t.state);let n=new Map(O.blockers);n.set(e,t),ae({blockers:n})}function ot(e){let{currentLocation:t,nextLocation:r,historyAction:n}=e;if(0===re.size)return;re.size>1&&h(!1,"A router only supports one blocker at a time");let a=Array.from(re.entries()),[o,i]=a[a.length-1],s=O.blockers.get(o);return s&&"proceeding"===s.state?void 0:i({currentLocation:t,nextLocation:r,historyAction:n})?o:void 0}function it(e){let t=Ne(404,{pathname:e}),r=s||f,{matches:n,route:a}=Fe(r);return st(),{notFoundMatches:n,route:a,error:t}}function st(e){let t=[];return te.forEach(((r,n)=>{e&&!e(n)||(r.cancel(),t.push(n),te.delete(n))})),t}function lt(e,t){return L&&L(e,t.map((e=>R(e,O.loaderData))))||e.key}function ut(e,t){if(P){let r=lt(e,t),n=P[r];if("number"==typeof n)return n}return null}function ct(e,t,r){if(y){if(!e)return{active:!0,matches:E(t,r,m,!0)||[]};if(Object.keys(e[0].params).length>0)return{active:!0,matches:E(t,r,m,!0)}}return{active:!1,matches:null}}async function dt(e,t,r,n){if(!y)return{type:"success",matches:e};let o=e;for(;;){let e=null==s,i=s||f,l=c;try{await y({signal:r,path:t,matches:o,fetcherKey:n,patch:(e,t)=>{r.aborted||xe(e,t,i,l,a)}})}catch(e){return{type:"error",error:e,partialMatches:o}}finally{e&&!r.aborted&&(f=[...f])}if(r.aborted)return{type:"aborted"};let u=S(i,t,m);if(u)return{type:"success",matches:u};let d=E(i,t,m,!0);if(!d||o.length===d.length&&o.every(((e,t)=>e.route.id===d[t].route.id)))return{type:"success",matches:null};o=d}}return u={get basename(){return m},get future(){return x},get state(){return O},get routes(){return f},get window(){return t},initialize:function(){if(D=e.history.listen((t=>{let{action:r,location:n,delta:a}=t;if(j)return j(),void(j=void 0);h(0===re.size||null!=a,"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL.");let o=ot({currentLocation:O.location,nextLocation:n,historyAction:r});if(o&&null!=a){let t=new Promise((e=>{j=e}));return e.history.go(-1*a),void at(o,{state:"blocked",location:n,proceed(){at(o,{state:"proceeding",proceed:void 0,reset:void 0,location:n}),t.then((()=>e.history.go(a)))},reset(){let e=new Map(O.blockers);e.set(o,he),ae({blockers:e})}})}return ie(r,n)})),r){!function(e,t){try{let r=e.sessionStorage.getItem(me);if(r){let e=JSON.parse(r);for(let[r,n]of Object.entries(e||{}))n&&Array.isArray(n)&&t.set(r,new Set(n||[]))}}catch(e){}}(t,z);let e=()=>function(e,t){if(t.size>0){let r={};for(let[e,n]of t)r[e]=[...n];try{e.sessionStorage.setItem(me,JSON.stringify(r))}catch(e){h(!1,"Failed to save applied view transitions in sessionStorage ("+e+").")}}}(t,z);t.addEventListener("pagehide",e),H=()=>t.removeEventListener("pagehide",e)}return O.initialized||ie(i.Pop,O.location,{initialHydration:!0}),u},subscribe:function(e){return C.add(e),()=>C.delete(e)},enableScrollRestoration:function(e,t,r){if(P=e,k=t,L=r||null,!T&&O.navigation===ce){T=!0;let e=ut(O.location,O.matches);null!=e&&ae({restoreScrollPosition:e})}return()=>{P=null,k=null,L=null}},navigate:async function t(r,n){if("number"==typeof r)return void e.history.go(r);let a=ye(O.location,O.matches,m,x.v7_prependBasename,r,x.v7_relativeSplatPath,null==n?void 0:n.fromRouteId,null==n?void 0:n.relative),{path:s,submission:l,error:u}=ge(x.v7_normalizeFormMethod,!1,a,n),c=O.location,d=p(O.location,s,n&&n.state);d=o({},d,e.history.encodeLocation(d));let h=n&&null!=n.replace?n.replace:void 0,f=i.Push;!0===h?f=i.Replace:!1===h||null!=l&&Je(l.formMethod)&&l.formAction===O.location.pathname+O.location.search&&(f=i.Replace);let v=n&&"preventScrollReset"in n?!0===n.preventScrollReset:void 0,y=!0===(n&&n.flushSync),g=ot({currentLocation:c,nextLocation:d,historyAction:f});if(!g)return await ie(f,d,{submission:l,pendingError:u,preventScrollReset:v,replace:n&&n.replace,enableViewTransition:n&&n.viewTransition,flushSync:y});at(g,{state:"blocked",location:d,proceed(){at(g,{state:"proceeding",proceed:void 0,reset:void 0,location:d}),t(r,n)},reset(){let e=new Map(O.blockers);e.set(g,he),ae({blockers:e})}})},fetch:function(t,r,a,o){if(n)throw new Error("router.fetch() was called during the server render, but it shouldn't be. You are likely calling a useFetcher() method in the body of your component. Try moving it to a useEffect or a callback.");Ie(t);let i=!0===(o&&o.flushSync),l=s||f,u=ye(O.location,O.matches,m,x.v7_prependBasename,a,x.v7_relativeSplatPath,r,null==o?void 0:o.relative),c=S(l,u,m),h=ct(c,l,u);if(h.active&&h.matches&&(c=h.matches),!c)return void De(t,r,Ne(404,{pathname:u}),{flushSync:i});let{path:p,submission:v,error:y}=ge(x.v7_normalizeFormMethod,!0,u,o);if(y)return void De(t,r,y,{flushSync:i});let g=Qe(c,p),b=!0===(o&&o.preventScrollReset);v&&Je(v.formMethod)?async function(t,r,n,a,o,i,l,u,c){function h(e){if(!e.route.action&&!e.route.lazy){let e=Ne(405,{method:c.formMethod,pathname:n,routeId:r});return De(t,r,e,{flushSync:l}),!0}return!1}if(Ee(),Q.delete(t),!i&&h(a))return;let p=O.fetchers.get(t);Re(t,function(e,t){return{state:"submitting",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t?t.data:void 0}}(c,p),{flushSync:l});let v=new AbortController,y=Te(e.history,n,v.signal,c);if(i){let e=await dt(o,new URL(y.url).pathname,y.signal,t);if("aborted"===e.type)return;if("error"===e.type)return void De(t,r,e.error,{flushSync:l});if(!e.matches)return void De(t,r,Ne(404,{pathname:n}),{flushSync:l});if(h(a=Qe(o=e.matches,n)))return}J.set(t,v);let g=q,b=(await ve("action",0,y,[a],o,t))[a.route.id];if(y.signal.aborted)return void(J.get(t)===v&&J.delete(t));if(x.v7_fetcherPersist&&ee.has(t)){if(Ke(b)||We(b))return void Re(t,rt(void 0))}else{if(Ke(b))return J.delete(t),Y>g?void Re(t,rt(void 0)):(G.add(t),Re(t,tt(c)),le(y,b,!1,{fetcherSubmission:c,preventScrollReset:u}));if(We(b))return void De(t,r,b.error)}if(He(b))throw Ne(400,{type:"defer-action"});let w=O.navigation.location||O.location,E=Te(e.history,w,v.signal),R=s||f,D="idle"!==O.navigation.state?S(R,O.navigation.location,m):O.matches;d(D,"Didn't find any matches after fetcher action");let C=++q;X.set(t,C);let P=tt(c,b.data);O.fetchers.set(t,P);let[L,k]=we(e.history,O,D,c,w,!1,x.v7_skipActionErrorRevalidation,K,$,V,ee,Q,G,R,m,[a.route.id,b]);k.filter((e=>e.key!==t)).forEach((e=>{let t=e.key,r=O.fetchers.get(t),n=tt(void 0,r?r.data:void 0);O.fetchers.set(t,n),Ie(t),e.controller&&J.set(t,e.controller)})),ae({fetchers:new Map(O.fetchers)});let T=()=>k.forEach((e=>Ie(e.key)));v.signal.addEventListener("abort",T);let{loaderResults:_,fetcherResults:A}=await be(O,D,L,k,E);if(v.signal.aborted)return;v.signal.removeEventListener("abort",T),X.delete(t),J.delete(t),k.forEach((e=>J.delete(e.key)));let M=Be(_);if(M)return le(E,M.result,!1,{preventScrollReset:u});if(M=Be(A),M)return G.add(M.key),le(E,M.result,!1,{preventScrollReset:u});let{loaderData:j,errors:N}=Me(O,D,_,void 0,k,A,te);if(O.fetchers.has(t)){let e=rt(b.data);O.fetchers.set(t,e)}Ge(C),"loading"===O.navigation.state&&C>Y?(d(F,"Expected pending action"),U&&U.abort(),oe(O.navigation.location,{matches:D,loaderData:j,errors:N,fetchers:new Map(O.fetchers)})):(ae({errors:N,loaderData:Ue(O.loaderData,j,D,N),fetchers:new Map(O.fetchers)}),K=!1)}(t,r,p,g,c,h.active,i,b,v):(Q.set(t,{routeId:r,path:p}),async function(t,r,n,a,o,i,s,l,u){let c=O.fetchers.get(t);Re(t,tt(u,c?c.data:void 0),{flushSync:s});let h=new AbortController,f=Te(e.history,n,h.signal);if(i){let e=await dt(o,new URL(f.url).pathname,f.signal,t);if("aborted"===e.type)return;if("error"===e.type)return void De(t,r,e.error,{flushSync:s});if(!e.matches)return void De(t,r,Ne(404,{pathname:n}),{flushSync:s});a=Qe(o=e.matches,n)}J.set(t,h);let p=q,m=(await ve("loader",0,f,[a],o,t))[a.route.id];if(He(m)&&(m=await Xe(m,f.signal,!0)||m),J.get(t)===h&&J.delete(t),!f.signal.aborted){if(!ee.has(t))return Ke(m)?Y>p?void Re(t,rt(void 0)):(G.add(t),void await le(f,m,!1,{preventScrollReset:l})):void(We(m)?De(t,r,m.error):(d(!He(m),"Unhandled fetcher deferred data"),Re(t,rt(m.data))));Re(t,rt(void 0))}}(t,r,p,g,c,h.active,i,b,v))},revalidate:function(){Ee(),ae({revalidation:"loading"}),"submitting"!==O.navigation.state&&("idle"!==O.navigation.state?ie(F||O.historyAction,O.navigation.location,{overrideNavigation:O.navigation,enableViewTransition:!0===I}):ie(O.historyAction,O.location,{startUninterruptedRevalidation:!0}))},createHref:t=>e.history.createHref(t),encodeLocation:t=>e.history.encodeLocation(t),getFetcher:_e,deleteFetcher:function(e){let t=(Z.get(e)||0)-1;t<=0?(Z.delete(e),ee.add(e),x.v7_fetcherPersist||Ae(e)):Z.set(e,t),ae({fetchers:new Map(O.fetchers)})},dispose:function(){D&&D(),H&&H(),C.clear(),U&&U.abort(),O.fetchers.forEach(((e,t)=>Ae(t))),O.blockers.forEach(((e,t)=>nt(t)))},getBlocker:function(e,t){let r=O.blockers.get(e)||he;return re.get(e)!==t&&re.set(e,t),r},deleteBlocker:nt,patchRoutes:function(e,t){let r=null==s;xe(e,t,s||f,c,a),r&&(f=[...f],ae({}))},_internalFetchControllers:J,_internalActiveDeferreds:te,_internalSetRoutes:function(e){c={},s=w(e,a,void 0,c)}},u}function ye(e,t,r,n,a,o,i,s){let l,u;if(i){l=[];for(let e of t)if(l.push(e),e.route.id===i){u=e;break}}else l=t,u=t[t.length-1];let c=W(a||".",H(l,o),N(e.pathname,r)||e.pathname,"path"===s);if(null==a&&(c.search=e.search,c.hash=e.hash),(null==a||""===a||"."===a)&&u){let e=Ge(c.search);if(u.route.index&&!e)c.search=c.search?c.search.replace(/^\?/,"?index&"):"?index";else if(!u.route.index&&e){let e=new URLSearchParams(c.search),t=e.getAll("index");e.delete("index"),t.filter((e=>e)).forEach((t=>e.append("index",t)));let r=e.toString();c.search=r?"?"+r:""}}return n&&"/"!==r&&(c.pathname="/"===c.pathname?r:K([r,c.pathname])),m(c)}function ge(e,t,r,n){if(!n||!function(e){return null!=e&&("formData"in e&&null!=e.formData||"body"in e&&void 0!==e.body)}(n))return{path:r};if(n.formMethod&&(a=n.formMethod,!se.has(a.toLowerCase())))return{path:r,error:Ne(405,{method:n.formMethod})};var a;let o,i,s=()=>({path:r,error:Ne(400,{type:"invalid-body"})}),l=n.formMethod||"get",u=e?l.toUpperCase():l.toLowerCase(),c=Ie(r);if(void 0!==n.body){if("text/plain"===n.formEncType){if(!Je(u))return s();let e="string"==typeof n.body?n.body:n.body instanceof FormData||n.body instanceof URLSearchParams?Array.from(n.body.entries()).reduce(((e,t)=>{let[r,n]=t;return""+e+r+"="+n+"\n"}),""):String(n.body);return{path:r,submission:{formMethod:u,formAction:c,formEncType:n.formEncType,formData:void 0,json:void 0,text:e}}}if("application/json"===n.formEncType){if(!Je(u))return s();try{let e="string"==typeof n.body?JSON.parse(n.body):n.body;return{path:r,submission:{formMethod:u,formAction:c,formEncType:n.formEncType,formData:void 0,json:e,text:void 0}}}catch(e){return s()}}}if(d("function"==typeof FormData,"FormData is not available in this environment"),n.formData)o=_e(n.formData),i=n.formData;else if(n.body instanceof FormData)o=_e(n.body),i=n.body;else if(n.body instanceof URLSearchParams)o=n.body,i=Ae(o);else if(null==n.body)o=new URLSearchParams,i=new FormData;else try{o=new URLSearchParams(n.body),i=Ae(o)}catch(e){return s()}let h={formMethod:u,formAction:c,formEncType:n&&n.formEncType||"application/x-www-form-urlencoded",formData:i,json:void 0,text:void 0};if(Je(h.formMethod))return{path:r,submission:h};let f=v(r);return t&&f.search&&Ge(f.search)&&o.append("index",""),f.search="?"+o,{path:m(f),submission:h}}function be(e,t,r){void 0===r&&(r=!1);let n=e.findIndex((e=>e.route.id===t));return n>=0?e.slice(0,r?n+1:n):e}function we(e,t,r,n,a,i,s,l,u,c,d,h,f,p,m,v){let y=v?We(v[1])?v[1].error:v[1].data:void 0,g=e.createURL(t.location),b=e.createURL(a),w=r;i&&t.errors?w=be(r,Object.keys(t.errors)[0],!0):v&&We(v[1])&&(w=be(r,v[0]));let E=v?v[1].statusCode:void 0,R=s&&E&&E>=400,x=w.filter(((e,r)=>{let{route:a}=e;if(a.lazy)return!0;if(null==a.loader)return!1;if(i)return Se(a,t.loaderData,t.errors);if(function(e,t,r){let n=!t||r.route.id!==t.route.id,a=void 0===e[r.route.id];return n||a}(t.loaderData,t.matches[r],e)||u.some((t=>t===e.route.id)))return!0;let s=t.matches[r],c=e;return Re(e,o({currentUrl:g,currentParams:s.params,nextUrl:b,nextParams:c.params},n,{actionResult:y,actionStatus:E,defaultShouldRevalidate:!R&&(l||g.pathname+g.search===b.pathname+b.search||g.search!==b.search||Ee(s,c))}))})),D=[];return h.forEach(((e,a)=>{if(i||!r.some((t=>t.route.id===e.routeId))||d.has(a))return;let s=S(p,e.path,m);if(!s)return void D.push({key:a,routeId:e.routeId,path:e.path,matches:null,match:null,controller:null});let u=t.fetchers.get(a),h=Qe(s,e.path),v=!1;f.has(a)?v=!1:c.has(a)?(c.delete(a),v=!0):v=u&&"idle"!==u.state&&void 0===u.data?l:Re(h,o({currentUrl:g,currentParams:t.matches[t.matches.length-1].params,nextUrl:b,nextParams:r[r.length-1].params},n,{actionResult:y,actionStatus:E,defaultShouldRevalidate:!R&&l})),v&&D.push({key:a,routeId:e.routeId,path:e.path,matches:s,match:h,controller:new AbortController})})),[x,D]}function Se(e,t,r){if(e.lazy)return!0;if(!e.loader)return!1;let n=null!=t&&void 0!==t[e.id],a=null!=r&&void 0!==r[e.id];return!(!n&&a)&&("function"==typeof e.loader&&!0===e.loader.hydrate||!n&&!a)}function Ee(e,t){let r=e.route.path;return e.pathname!==t.pathname||null!=r&&r.endsWith("*")&&e.params["*"]!==t.params["*"]}function Re(e,t){if(e.route.shouldRevalidate){let r=e.route.shouldRevalidate(t);if("boolean"==typeof r)return r}return t.defaultShouldRevalidate}function xe(e,t,r,n,a){var o;let i;if(e){let t=n[e];d(t,"No route found to patch children into: routeId = "+e),t.children||(t.children=[]),i=t.children}else i=r;let s=w(t.filter((e=>!i.some((t=>De(e,t))))),a,[e||"_","patch",String((null==(o=i)?void 0:o.length)||"0")],n);i.push(...s)}function De(e,t){return"id"in e&&"id"in t&&e.id===t.id||e.index===t.index&&e.path===t.path&&e.caseSensitive===t.caseSensitive&&(!(e.children&&0!==e.children.length||t.children&&0!==t.children.length)||e.children.every(((e,r)=>{var n;return null==(n=t.children)?void 0:n.some((t=>De(e,t)))})))}async function Ce(e){let{matches:t}=e,r=t.filter((e=>e.shouldLoad));return(await Promise.all(r.map((e=>e.resolve())))).reduce(((e,t,n)=>Object.assign(e,{[r[n].route.id]:t})),{})}async function Pe(e){let{result:t,type:r}=e;if(Ve(t)){let e;try{let r=t.headers.get("Content-Type");e=r&&/\bapplication\/json\b/.test(r)?null==t.body?null:await t.json():await t.text()}catch(e){return{type:g.error,error:e}}return r===g.error?{type:g.error,error:new re(t.status,t.statusText,e),statusCode:t.status,headers:t.headers}:{type:g.data,data:e,statusCode:t.status,headers:t.headers}}var n,a,o,i,s,l,u,c;return r===g.error?$e(t)?t.data instanceof Error?{type:g.error,error:t.data,statusCode:null==(o=t.init)?void 0:o.status,headers:null!=(i=t.init)&&i.headers?new Headers(t.init.headers):void 0}:{type:g.error,error:new re((null==(n=t.init)?void 0:n.status)||500,void 0,t.data),statusCode:ne(t)?t.status:void 0,headers:null!=(a=t.init)&&a.headers?new Headers(t.init.headers):void 0}:{type:g.error,error:t,statusCode:ne(t)?t.status:void 0}:function(e){let t=e;return t&&"object"==typeof t&&"object"==typeof t.data&&"function"==typeof t.subscribe&&"function"==typeof t.cancel&&"function"==typeof t.resolveData}(t)?{type:g.deferred,deferredData:t,statusCode:null==(s=t.init)?void 0:s.status,headers:(null==(l=t.init)?void 0:l.headers)&&new Headers(t.init.headers)}:$e(t)?{type:g.data,data:t.data,statusCode:null==(u=t.init)?void 0:u.status,headers:null!=(c=t.init)&&c.headers?new Headers(t.init.headers):void 0}:{type:g.data,data:t}}function Le(e,t,r,n,a,o){let i=e.headers.get("Location");if(d(i,"Redirects returned/thrown from loaders/actions must have a Location header"),!fe.test(i)){let s=n.slice(0,n.findIndex((e=>e.route.id===r))+1);i=ye(new URL(t.url),s,a,!0,i,o),e.headers.set("Location",i)}return e}function ke(e,t,r){if(fe.test(e)){let n=e,a=n.startsWith("//")?new URL(t.protocol+n):new URL(n),o=null!=N(a.pathname,r);if(a.origin===t.origin&&o)return a.pathname+a.search+a.hash}return e}function Te(e,t,r,n){let a=e.createURL(Ie(t)).toString(),o={signal:r};if(n&&Je(n.formMethod)){let{formMethod:e,formEncType:t}=n;o.method=e.toUpperCase(),"application/json"===t?(o.headers=new Headers({"Content-Type":t}),o.body=JSON.stringify(n.json)):"text/plain"===t?o.body=n.text:"application/x-www-form-urlencoded"===t&&n.formData?o.body=_e(n.formData):o.body=n.formData}return new Request(a,o)}function _e(e){let t=new URLSearchParams;for(let[r,n]of e.entries())t.append(r,"string"==typeof n?n:n.name);return t}function Ae(e){let t=new FormData;for(let[r,n]of e.entries())t.append(r,n);return t}function Me(e,t,r,n,a,i,s){let{loaderData:l,errors:u}=function(e,t,r,n,a){let o,i={},s=null,l=!1,u={},c=r&&We(r[1])?r[1].error:void 0;return e.forEach((r=>{if(!(r.route.id in t))return;let h=r.route.id,f=t[h];if(d(!Ke(f),"Cannot handle redirect results in processLoaderData"),We(f)){let t=f.error;if(void 0!==c&&(t=c,c=void 0),s=s||{},a)s[h]=t;else{let r=Oe(e,h);null==s[r.route.id]&&(s[r.route.id]=t)}i[h]=void 0,l||(l=!0,o=ne(f.error)?f.error.status:500),f.headers&&(u[h]=f.headers)}else He(f)?(n.set(h,f.deferredData),i[h]=f.deferredData.data,null==f.statusCode||200===f.statusCode||l||(o=f.statusCode),f.headers&&(u[h]=f.headers)):(i[h]=f.data,f.statusCode&&200!==f.statusCode&&!l&&(o=f.statusCode),f.headers&&(u[h]=f.headers))})),void 0!==c&&r&&(s={[r[0]]:c},i[r[0]]=void 0),{loaderData:i,errors:s,statusCode:o||200,loaderHeaders:u}}(t,r,n,s,!1);return a.forEach((t=>{let{key:r,match:n,controller:a}=t,s=i[r];if(d(s,"Did not find corresponding fetcher result"),!a||!a.signal.aborted)if(We(s)){let t=Oe(e.matches,null==n?void 0:n.route.id);u&&u[t.route.id]||(u=o({},u,{[t.route.id]:s.error})),e.fetchers.delete(r)}else if(Ke(s))d(!1,"Unhandled fetcher revalidation redirect");else if(He(s))d(!1,"Unhandled fetcher deferred data");else{let t=rt(s.data);e.fetchers.set(r,t)}})),{loaderData:l,errors:u}}function Ue(e,t,r,n){let a=o({},t);for(let o of r){let r=o.route.id;if(t.hasOwnProperty(r)?void 0!==t[r]&&(a[r]=t[r]):void 0!==e[r]&&o.route.loader&&(a[r]=e[r]),n&&n.hasOwnProperty(r))break}return a}function je(e){return e?We(e[1])?{actionData:{}}:{actionData:{[e[0]]:e[1].data}}:{}}function Oe(e,t){return(t?e.slice(0,e.findIndex((e=>e.route.id===t))+1):[...e]).reverse().find((e=>!0===e.route.hasErrorBoundary))||e[0]}function Fe(e){let t=1===e.length?e[0]:e.find((e=>e.index||!e.path||"/"===e.path))||{id:"__shim-error-route__"};return{matches:[{params:{},pathname:"",pathnameBase:"",route:t}],route:t}}function Ne(e,t){let{pathname:r,routeId:n,method:a,type:o,message:i}=void 0===t?{}:t,s="Unknown Server Error",l="Unknown @remix-run/router error";return 400===e?(s="Bad Request",a&&r&&n?l="You made a "+a+' request to "'+r+'" but did not provide a `loader` for route "'+n+'", so there is no way to handle the request.':"defer-action"===o?l="defer() is not supported in actions":"invalid-body"===o&&(l="Unable to encode submission body")):403===e?(s="Forbidden",l='Route "'+n+'" does not match URL "'+r+'"'):404===e?(s="Not Found",l='No route matches URL "'+r+'"'):405===e&&(s="Method Not Allowed",a&&r&&n?l="You made a "+a.toUpperCase()+' request to "'+r+'" but did not provide an `action` for route "'+n+'", so there is no way to handle the request.':a&&(l='Invalid request method "'+a.toUpperCase()+'"')),new re(e||500,s,new Error(l),!0)}function Be(e){let t=Object.entries(e);for(let e=t.length-1;e>=0;e--){let[r,n]=t[e];if(Ke(n))return{key:r,result:n}}}function Ie(e){return m(o({},"string"==typeof e?v(e):e,{hash:""}))}function ze(e){return Ve(e.result)&&le.has(e.result.status)}function He(e){return e.type===g.deferred}function We(e){return e.type===g.error}function Ke(e){return(e&&e.type)===g.redirect}function $e(e){return"object"==typeof e&&null!=e&&"type"in e&&"data"in e&&"init"in e&&"DataWithResponseInit"===e.type}function Ve(e){return null!=e&&"number"==typeof e.status&&"string"==typeof e.statusText&&"object"==typeof e.headers&&void 0!==e.body}function Je(e){return oe.has(e.toLowerCase())}async function qe(e,t,r,n,a){let o=Object.entries(t);for(let i=0;i(null==e?void 0:e.route.id)===s));if(!u)continue;let c=n.find((e=>e.route.id===u.route.id)),d=null!=c&&!Ee(c,u)&&void 0!==(a&&a[u.route.id]);He(l)&&d&&await Xe(l,r,!1).then((e=>{e&&(t[s]=e)}))}}async function Ye(e,t,r){for(let n=0;n(null==e?void 0:e.route.id)===o))&&He(s)&&(d(i,"Expected an AbortController for revalidating fetcher deferred result"),await Xe(s,i.signal,!0).then((e=>{e&&(t[a]=e)})))}}async function Xe(e,t,r){if(void 0===r&&(r=!1),!await e.deferredData.resolveData(t)){if(r)try{return{type:g.data,data:e.deferredData.unwrappedData}}catch(e){return{type:g.error,error:e}}return{type:g.data,data:e.deferredData.data}}}function Ge(e){return new URLSearchParams(e).getAll("index").some((e=>""===e))}function Qe(e,t){let r="string"==typeof t?v(t).search:t.search;if(e[e.length-1].route.index&&Ge(r||""))return e[e.length-1];let n=z(e);return n[n.length-1]}function Ze(e){let{formMethod:t,formAction:r,formEncType:n,text:a,formData:o,json:i}=e;if(t&&r&&n)return null!=a?{formMethod:t,formAction:r,formEncType:n,formData:void 0,json:void 0,text:a}:null!=o?{formMethod:t,formAction:r,formEncType:n,formData:o,json:void 0,text:void 0}:void 0!==i?{formMethod:t,formAction:r,formEncType:n,formData:void 0,json:i,text:void 0}:void 0}function et(e,t){return t?{state:"loading",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}:{state:"loading",location:e,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0}}function tt(e,t){return e?{state:"loading",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t}:{state:"loading",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:t}}function rt(e){return{state:"idle",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:e}}function nt(){return nt=Object.assign?Object.assign.bind():function(e){for(var t=1;tO(e,F(t))),[t,e])}function vt(e){n.useContext(st).static||n.useLayoutEffect(e)}function yt(){let{isDataRoute:e}=n.useContext(ut);return e?function(){let{router:e}=At(Tt.UseNavigateStable),t=Ut(_t.UseNavigateStable),r=n.useRef(!1);return vt((()=>{r.current=!0})),n.useCallback((function(n,a){void 0===a&&(a={}),r.current&&("number"==typeof n?e.navigate(n):e.navigate(n,nt({fromRouteId:t},a)))}),[e,t])}():function(){ht()||d(!1);let e=n.useContext(at),{basename:t,future:r,navigator:a}=n.useContext(st),{matches:o}=n.useContext(ut),{pathname:i}=ft(),s=JSON.stringify(H(o,r.v7_relativeSplatPath)),l=n.useRef(!1);return vt((()=>{l.current=!0})),n.useCallback((function(r,n){if(void 0===n&&(n={}),!l.current)return;if("number"==typeof r)return void a.go(r);let o=W(r,JSON.parse(s),i,"path"===n.relative);null==e&&"/"!==t&&(o.pathname="/"===o.pathname?t:K([t,o.pathname])),(n.replace?a.replace:a.push)(o,n.state,n)}),[t,a,s,i,e])}()}const gt=n.createContext(null);function bt(){return n.useContext(gt)}function wt(e){let t=n.useContext(ut).outlet;return t?n.createElement(gt.Provider,{value:e},t):t}function St(){let{matches:e}=n.useContext(ut),t=e[e.length-1];return t?t.params:{}}function Et(e,t){let{relative:r}=void 0===t?{}:t,{future:a}=n.useContext(st),{matches:o}=n.useContext(ut),{pathname:i}=ft(),s=JSON.stringify(H(o,a.v7_relativeSplatPath));return n.useMemo((()=>W(e,JSON.parse(s),i,"path"===r)),[e,s,i,r])}function Rt(e,t){return xt(e,t)}function xt(e,t,r,a){ht()||d(!1);let{navigator:o,static:s}=n.useContext(st),{matches:l}=n.useContext(ut),u=l[l.length-1],c=u?u.params:{},h=(u&&u.pathname,u?u.pathnameBase:"/");u&&u.route;let f,p=ft();if(t){var m;let e="string"==typeof t?v(t):t;"/"===h||(null==(m=e.pathname)?void 0:m.startsWith(h))||d(!1),f=e}else f=p;let y=f.pathname||"/",g=y;if("/"!==h){let e=h.replace(/^\//,"").split("/");g="/"+y.replace(/^\//,"").split("/").slice(e.length).join("/")}let b=!s&&r&&r.matches&&r.matches.length>0?r.matches:S(e,{pathname:g}),w=kt(b&&b.map((e=>Object.assign({},e,{params:Object.assign({},c,e.params),pathname:K([h,o.encodeLocation?o.encodeLocation(e.pathname).pathname:e.pathname]),pathnameBase:"/"===e.pathnameBase?h:K([h,o.encodeLocation?o.encodeLocation(e.pathnameBase).pathname:e.pathnameBase])}))),l,r,a);return t&&w?n.createElement(lt.Provider,{value:{location:nt({pathname:"/",search:"",hash:"",state:null,key:"default"},f),navigationType:i.Pop}},w):w}function Dt(){let e=Ht(),t=ne(e)?e.status+" "+e.statusText:e instanceof Error?e.message:JSON.stringify(e),r=e instanceof Error?e.stack:null,a={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return n.createElement(n.Fragment,null,n.createElement("h2",null,"Unexpected Application Error!"),n.createElement("h3",{style:{fontStyle:"italic"}},t),r?n.createElement("pre",{style:a},r):null,null)}const Ct=n.createElement(Dt,null);class Pt extends n.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||"idle"!==t.revalidation&&"idle"===e.revalidation?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:void 0!==e.error?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){console.error("React Router caught the following error during render",e,t)}render(){return void 0!==this.state.error?n.createElement(ut.Provider,{value:this.props.routeContext},n.createElement(ct.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function Lt(e){let{routeContext:t,match:r,children:a}=e,o=n.useContext(at);return o&&o.static&&o.staticContext&&(r.route.errorElement||r.route.ErrorBoundary)&&(o.staticContext._deepestRenderedBoundaryId=r.route.id),n.createElement(ut.Provider,{value:t},a)}function kt(e,t,r,a){var o;if(void 0===t&&(t=[]),void 0===r&&(r=null),void 0===a&&(a=null),null==e){var i;if(!r)return null;if(r.errors)e=r.matches;else{if(!(null!=(i=a)&&i.v7_partialHydration&&0===t.length&&!r.initialized&&r.matches.length>0))return null;e=r.matches}}let s=e,l=null==(o=r)?void 0:o.errors;if(null!=l){let e=s.findIndex((e=>e.route.id&&void 0!==(null==l?void 0:l[e.route.id])));e>=0||d(!1),s=s.slice(0,Math.min(s.length,e+1))}let u=!1,c=-1;if(r&&a&&a.v7_partialHydration)for(let e=0;e=0?s.slice(0,c+1):[s[0]];break}}}return s.reduceRight(((e,a,o)=>{let i,d=!1,h=null,f=null;var p;r&&(i=l&&a.route.id?l[a.route.id]:void 0,h=a.route.errorElement||Ct,u&&(c<0&&0===o?(Jt[p="route-fallback"]||(Jt[p]=!0),d=!0,f=null):c===o&&(d=!0,f=a.route.hydrateFallbackElement||null)));let m=t.concat(s.slice(0,o+1)),v=()=>{let t;return t=i?h:d?f:a.route.Component?n.createElement(a.route.Component,null):a.route.element?a.route.element:e,n.createElement(Lt,{match:a,routeContext:{outlet:e,matches:m,isDataRoute:null!=r},children:t})};return r&&(a.route.ErrorBoundary||a.route.errorElement||0===o)?n.createElement(Pt,{location:r.location,revalidation:r.revalidation,component:h,error:i,children:v(),routeContext:{outlet:null,matches:m,isDataRoute:!0}}):v()}),null)}var Tt=function(e){return e.UseBlocker="useBlocker",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e}(Tt||{}),_t=function(e){return e.UseBlocker="useBlocker",e.UseLoaderData="useLoaderData",e.UseActionData="useActionData",e.UseRouteError="useRouteError",e.UseNavigation="useNavigation",e.UseRouteLoaderData="useRouteLoaderData",e.UseMatches="useMatches",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e.UseRouteId="useRouteId",e}(_t||{});function At(e){let t=n.useContext(at);return t||d(!1),t}function Mt(e){let t=n.useContext(ot);return t||d(!1),t}function Ut(e){let t=function(){let e=n.useContext(ut);return e||d(!1),e}(),r=t.matches[t.matches.length-1];return r.route.id||d(!1),r.route.id}function jt(){return Ut(_t.UseRouteId)}function Ot(){return Mt(_t.UseNavigation).navigation}function Ft(){let e=At(Tt.UseRevalidator),t=Mt(_t.UseRevalidator);return n.useMemo((()=>({revalidate:e.router.revalidate,state:t.revalidation})),[e.router.revalidate,t.revalidation])}function Nt(){let{matches:e,loaderData:t}=Mt(_t.UseMatches);return n.useMemo((()=>e.map((e=>R(e,t)))),[e,t])}function Bt(){let e=Mt(_t.UseLoaderData),t=Ut(_t.UseLoaderData);if(!e.errors||null==e.errors[t])return e.loaderData[t];console.error("You cannot `useLoaderData` in an errorElement (routeId: "+t+")")}function It(e){return Mt(_t.UseRouteLoaderData).loaderData[e]}function zt(){let e=Mt(_t.UseActionData),t=Ut(_t.UseLoaderData);return e.actionData?e.actionData[t]:void 0}function Ht(){var e;let t=n.useContext(ct),r=Mt(_t.UseRouteError),a=Ut(_t.UseRouteError);return void 0!==t?t:null==(e=r.errors)?void 0:e[a]}function Wt(){let e=n.useContext(it);return null==e?void 0:e._data}function Kt(){let e=n.useContext(it);return null==e?void 0:e._error}let $t=0;function Vt(e){let{router:t,basename:r}=At(Tt.UseBlocker),a=Mt(_t.UseBlocker),[o,i]=n.useState(""),s=n.useCallback((t=>{if("function"!=typeof e)return!!e;if("/"===r)return e(t);let{currentLocation:n,nextLocation:a,historyAction:o}=t;return e({currentLocation:nt({},n,{pathname:N(n.pathname,r)||n.pathname}),nextLocation:nt({},a,{pathname:N(a.pathname,r)||a.pathname}),historyAction:o})}),[r,e]);return n.useEffect((()=>{let e=String(++$t);return i(e),()=>t.deleteBlocker(e)}),[t]),n.useEffect((()=>{""!==o&&t.getBlocker(o,s)}),[t,o,s]),o&&a.blockers.has(o)?a.blockers.get(o):he}const Jt={},qt=(e,t,r)=>{};function Yt(e,t){void 0===(null==e?void 0:e.v7_startTransition)&&qt("v7_startTransition","React Router will begin wrapping state updates in `React.startTransition` in v7","https://reactrouter.com/v6/upgrading/future#v7_starttransition"),void 0!==(null==e?void 0:e.v7_relativeSplatPath)||t&&t.v7_relativeSplatPath||qt("v7_relativeSplatPath","Relative route resolution within Splat routes is changing in v7","https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath"),t&&(void 0===t.v7_fetcherPersist&&qt("v7_fetcherPersist","The persistence behavior of fetchers is changing in v7","https://reactrouter.com/v6/upgrading/future#v7_fetcherpersist"),void 0===t.v7_normalizeFormMethod&&qt("v7_normalizeFormMethod","Casing of `formMethod` fields is being normalized to uppercase in v7","https://reactrouter.com/v6/upgrading/future#v7_normalizeformmethod"),void 0===t.v7_partialHydration&&qt("v7_partialHydration","`RouterProvider` hydration behavior is changing in v7","https://reactrouter.com/v6/upgrading/future#v7_partialhydration"),void 0===t.v7_skipActionErrorRevalidation&&qt("v7_skipActionErrorRevalidation","The revalidation behavior after 4xx/5xx `action` responses is changing in v7","https://reactrouter.com/v6/upgrading/future#v7_skipactionerrorrevalidation"))}const Xt=n.startTransition;function Gt(e){let{basename:t,children:r,initialEntries:a,initialIndex:o,future:i}=e,s=n.useRef();null==s.current&&(s.current=l({initialEntries:a,initialIndex:o,v5Compat:!0}));let u=s.current,[c,d]=n.useState({action:u.action,location:u.location}),{v7_startTransition:h}=i||{},f=n.useCallback((e=>{h&&Xt?Xt((()=>d(e))):d(e)}),[d,h]);return n.useLayoutEffect((()=>u.listen(f)),[u,f]),n.useEffect((()=>Yt(i)),[i]),n.createElement(tr,{basename:t,children:r,location:c.location,navigationType:c.action,navigator:u,future:i})}function Qt(e){let{to:t,replace:r,state:a,relative:o}=e;ht()||d(!1);let{future:i,static:s}=n.useContext(st),{matches:l}=n.useContext(ut),{pathname:u}=ft(),c=yt(),h=W(t,H(l,i.v7_relativeSplatPath),u,"path"===o),f=JSON.stringify(h);return n.useEffect((()=>c(JSON.parse(f),{replace:r,state:a,relative:o})),[c,f,o,r,a]),null}function Zt(e){return wt(e.context)}function er(e){d(!1)}function tr(e){let{basename:t="/",children:r=null,location:a,navigationType:o=i.Pop,navigator:s,static:l=!1,future:u}=e;ht()&&d(!1);let c=t.replace(/^\/*/,"/"),h=n.useMemo((()=>({basename:c,navigator:s,static:l,future:nt({v7_relativeSplatPath:!1},u)})),[c,u,s,l]);"string"==typeof a&&(a=v(a));let{pathname:f="/",search:p="",hash:m="",state:y=null,key:g="default"}=a,b=n.useMemo((()=>{let e=N(f,c);return null==e?null:{location:{pathname:e,search:p,hash:m,state:y,key:g},navigationType:o}}),[c,f,p,m,y,g,o]);return null==b?null:n.createElement(st.Provider,{value:h},n.createElement(lt.Provider,{children:r,value:b}))}function rr(e){let{children:t,location:r}=e;return Rt(lr(t),r)}function nr(e){let{children:t,errorElement:r,resolve:a}=e;return n.createElement(ir,{resolve:a,errorElement:r},n.createElement(sr,null,t))}var ar=function(e){return e[e.pending=0]="pending",e[e.success=1]="success",e[e.error=2]="error",e}(ar||{});const or=new Promise((()=>{}));class ir extends n.Component{constructor(e){super(e),this.state={error:null}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){console.error(" caught the following error during render",e,t)}render(){let{children:e,errorElement:t,resolve:r}=this.props,a=null,o=ar.pending;if(r instanceof Promise)if(this.state.error){o=ar.error;let e=this.state.error;a=Promise.reject().catch((()=>{})),Object.defineProperty(a,"_tracked",{get:()=>!0}),Object.defineProperty(a,"_error",{get:()=>e})}else r._tracked?(a=r,o="_error"in a?ar.error:"_data"in a?ar.success:ar.pending):(o=ar.pending,Object.defineProperty(r,"_tracked",{get:()=>!0}),a=r.then((e=>Object.defineProperty(r,"_data",{get:()=>e})),(e=>Object.defineProperty(r,"_error",{get:()=>e}))));else o=ar.success,a=Promise.resolve(),Object.defineProperty(a,"_tracked",{get:()=>!0}),Object.defineProperty(a,"_data",{get:()=>r});if(o===ar.error&&a._error instanceof Y)throw or;if(o===ar.error&&!t)throw a._error;if(o===ar.error)return n.createElement(it.Provider,{value:a,children:t});if(o===ar.success)return n.createElement(it.Provider,{value:a,children:e});throw a}}function sr(e){let{children:t}=e,r=Wt(),a="function"==typeof t?t(r):t;return n.createElement(n.Fragment,null,a)}function lr(e,t){void 0===t&&(t=[]);let r=[];return n.Children.forEach(e,((e,a)=>{if(!n.isValidElement(e))return;let o=[...t,a];if(e.type===n.Fragment)return void r.push.apply(r,lr(e.props.children,o));e.type!==er&&d(!1),e.props.index&&e.props.children&&d(!1);let i={id:e.props.id||o.join("-"),caseSensitive:e.props.caseSensitive,element:e.props.element,Component:e.props.Component,index:e.props.index,path:e.props.path,loader:e.props.loader,action:e.props.action,errorElement:e.props.errorElement,ErrorBoundary:e.props.ErrorBoundary,hasErrorBoundary:null!=e.props.ErrorBoundary||null!=e.props.errorElement,shouldRevalidate:e.props.shouldRevalidate,handle:e.props.handle,lazy:e.props.lazy};e.props.children&&(i.children=lr(e.props.children,o)),r.push(i)})),r}function ur(e){return kt(e)}function cr(e){let t={hasErrorBoundary:null!=e.ErrorBoundary||null!=e.errorElement};return e.Component&&Object.assign(t,{element:n.createElement(e.Component),Component:void 0}),e.HydrateFallback&&Object.assign(t,{hydrateFallbackElement:n.createElement(e.HydrateFallback),HydrateFallback:void 0}),e.ErrorBoundary&&Object.assign(t,{errorElement:n.createElement(e.ErrorBoundary),ErrorBoundary:void 0}),t}function dr(e,t){return ve({basename:null==t?void 0:t.basename,future:nt({},null==t?void 0:t.future,{v7_prependBasename:!0}),history:l({initialEntries:null==t?void 0:t.initialEntries,initialIndex:null==t?void 0:t.initialIndex}),hydrationData:null==t?void 0:t.hydrationData,routes:e,mapRouteProperties:cr,dataStrategy:null==t?void 0:t.dataStrategy,patchRoutesOnNavigation:null==t?void 0:t.patchRoutesOnNavigation}).initialize()}function hr(){return hr=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0||(a[r]=e[r]);return a}const pr="get",mr="application/x-www-form-urlencoded";function vr(e){return null!=e&&"string"==typeof e.tagName}function yr(e){return void 0===e&&(e=""),new URLSearchParams("string"==typeof e||Array.isArray(e)||e instanceof URLSearchParams?e:Object.keys(e).reduce(((t,r)=>{let n=e[r];return t.concat(Array.isArray(n)?n.map((e=>[r,e])):[[r,n]])}),[]))}let gr=null;const br=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function wr(e){return null==e||br.has(e)?e:null}const Sr=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],Er=["aria-current","caseSensitive","className","end","style","to","viewTransition","children"],Rr=["fetcherKey","navigate","reloadDocument","replace","state","method","action","onSubmit","relative","preventScrollReset","viewTransition"];try{window.__reactRouterVersion="6"}catch(e){}function xr(e,t){return ve({basename:null==t?void 0:t.basename,future:hr({},null==t?void 0:t.future,{v7_prependBasename:!0}),history:u({window:null==t?void 0:t.window}),hydrationData:(null==t?void 0:t.hydrationData)||Cr(),routes:e,mapRouteProperties:cr,dataStrategy:null==t?void 0:t.dataStrategy,patchRoutesOnNavigation:null==t?void 0:t.patchRoutesOnNavigation,window:null==t?void 0:t.window}).initialize()}function Dr(e,t){return ve({basename:null==t?void 0:t.basename,future:hr({},null==t?void 0:t.future,{v7_prependBasename:!0}),history:c({window:null==t?void 0:t.window}),hydrationData:(null==t?void 0:t.hydrationData)||Cr(),routes:e,mapRouteProperties:cr,dataStrategy:null==t?void 0:t.dataStrategy,patchRoutesOnNavigation:null==t?void 0:t.patchRoutesOnNavigation,window:null==t?void 0:t.window}).initialize()}function Cr(){var e;let t=null==(e=window)?void 0:e.__staticRouterHydrationData;return t&&t.errors&&(t=hr({},t,{errors:Pr(t.errors)})),t}function Pr(e){if(!e)return null;let t=Object.entries(e),r={};for(let[e,n]of t)if(n&&"RouteErrorResponse"===n.__type)r[e]=new re(n.status,n.statusText,n.data,!0===n.internal);else if(n&&"Error"===n.__type){if(n.__subType){let t=window[n.__subType];if("function"==typeof t)try{let a=new t(n.message);a.stack="",r[e]=a}catch(e){}}if(null==r[e]){let t=new Error(n.message);t.stack="",r[e]=t}}else r[e]=n;return r}const Lr=n.createContext({isTransitioning:!1}),kr=n.createContext(new Map),Tr=n.startTransition,_r=a.flushSync,Ar=n.useId;function Mr(e){_r?_r(e):e()}class Ur{constructor(){this.status="pending",this.promise=new Promise(((e,t)=>{this.resolve=t=>{"pending"===this.status&&(this.status="resolved",e(t))},this.reject=e=>{"pending"===this.status&&(this.status="rejected",t(e))}}))}}function jr(e){let{fallbackElement:t,router:r,future:a}=e,[o,i]=n.useState(r.state),[s,l]=n.useState(),[u,c]=n.useState({isTransitioning:!1}),[d,h]=n.useState(),[f,p]=n.useState(),[m,v]=n.useState(),y=n.useRef(new Map),{v7_startTransition:g}=a||{},b=n.useCallback((e=>{g?function(e){Tr?Tr(e):e()}(e):e()}),[g]),w=n.useCallback(((e,t)=>{let{deletedFetchers:n,flushSync:a,viewTransitionOpts:o}=t;e.fetchers.forEach(((e,t)=>{void 0!==e.data&&y.current.set(t,e.data)})),n.forEach((e=>y.current.delete(e)));let s=null==r.window||null==r.window.document||"function"!=typeof r.window.document.startViewTransition;if(o&&!s){if(a){Mr((()=>{f&&(d&&d.resolve(),f.skipTransition()),c({isTransitioning:!0,flushSync:!0,currentLocation:o.currentLocation,nextLocation:o.nextLocation})}));let t=r.window.document.startViewTransition((()=>{Mr((()=>i(e)))}));return t.finished.finally((()=>{Mr((()=>{h(void 0),p(void 0),l(void 0),c({isTransitioning:!1})}))})),void Mr((()=>p(t)))}f?(d&&d.resolve(),f.skipTransition(),v({state:e,currentLocation:o.currentLocation,nextLocation:o.nextLocation})):(l(e),c({isTransitioning:!0,flushSync:!1,currentLocation:o.currentLocation,nextLocation:o.nextLocation}))}else a?Mr((()=>i(e))):b((()=>i(e)))}),[r.window,f,d,y,b]);n.useLayoutEffect((()=>r.subscribe(w)),[r,w]),n.useEffect((()=>{u.isTransitioning&&!u.flushSync&&h(new Ur)}),[u]),n.useEffect((()=>{if(d&&s&&r.window){let e=s,t=d.promise,n=r.window.document.startViewTransition((async()=>{b((()=>i(e))),await t}));n.finished.finally((()=>{h(void 0),p(void 0),l(void 0),c({isTransitioning:!1})})),p(n)}}),[b,s,d,r.window]),n.useEffect((()=>{d&&s&&o.location.key===s.location.key&&d.resolve()}),[d,f,o.location,s]),n.useEffect((()=>{!u.isTransitioning&&m&&(l(m.state),c({isTransitioning:!0,flushSync:!1,currentLocation:m.currentLocation,nextLocation:m.nextLocation}),v(void 0))}),[u.isTransitioning,m]),n.useEffect((()=>{}),[]);let S=n.useMemo((()=>({createHref:r.createHref,encodeLocation:r.encodeLocation,go:e=>r.navigate(e),push:(e,t,n)=>r.navigate(e,{state:t,preventScrollReset:null==n?void 0:n.preventScrollReset}),replace:(e,t,n)=>r.navigate(e,{replace:!0,state:t,preventScrollReset:null==n?void 0:n.preventScrollReset})})),[r]),E=r.basename||"/",R=n.useMemo((()=>({router:r,navigator:S,static:!1,basename:E})),[r,S,E]),x=n.useMemo((()=>({v7_relativeSplatPath:r.future.v7_relativeSplatPath})),[r.future.v7_relativeSplatPath]);return n.useEffect((()=>Yt(a,r.future)),[a,r.future]),n.createElement(n.Fragment,null,n.createElement(at.Provider,{value:R},n.createElement(ot.Provider,{value:o},n.createElement(kr.Provider,{value:y.current},n.createElement(Lr.Provider,{value:u},n.createElement(tr,{basename:E,location:o.location,navigationType:o.historyAction,navigator:S,future:x},o.initialized||r.future.v7_partialHydration?n.createElement(Or,{routes:r.routes,future:r.future,state:o}):t))))),null)}const Or=n.memo(Fr);function Fr(e){let{routes:t,future:r,state:n}=e;return xt(t,void 0,n,r)}function Nr(e){let{basename:t,children:r,future:a,window:o}=e,i=n.useRef();null==i.current&&(i.current=u({window:o,v5Compat:!0}));let s=i.current,[l,c]=n.useState({action:s.action,location:s.location}),{v7_startTransition:d}=a||{},h=n.useCallback((e=>{d&&Tr?Tr((()=>c(e))):c(e)}),[c,d]);return n.useLayoutEffect((()=>s.listen(h)),[s,h]),n.useEffect((()=>Yt(a)),[a]),n.createElement(tr,{basename:t,children:r,location:l.location,navigationType:l.action,navigator:s,future:a})}function Br(e){let{basename:t,children:r,future:a,window:o}=e,i=n.useRef();null==i.current&&(i.current=c({window:o,v5Compat:!0}));let s=i.current,[l,u]=n.useState({action:s.action,location:s.location}),{v7_startTransition:d}=a||{},h=n.useCallback((e=>{d&&Tr?Tr((()=>u(e))):u(e)}),[u,d]);return n.useLayoutEffect((()=>s.listen(h)),[s,h]),n.useEffect((()=>Yt(a)),[a]),n.createElement(tr,{basename:t,children:r,location:l.location,navigationType:l.action,navigator:s,future:a})}function Ir(e){let{basename:t,children:r,future:a,history:o}=e,[i,s]=n.useState({action:o.action,location:o.location}),{v7_startTransition:l}=a||{},u=n.useCallback((e=>{l&&Tr?Tr((()=>s(e))):s(e)}),[s,l]);return n.useLayoutEffect((()=>o.listen(u)),[o,u]),n.useEffect((()=>Yt(a)),[a]),n.createElement(tr,{basename:t,children:r,location:i.location,navigationType:i.action,navigator:o,future:a})}const zr="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,Hr=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Wr=n.forwardRef((function(e,t){let r,{onClick:a,relative:o,reloadDocument:i,replace:s,state:l,target:u,to:c,preventScrollReset:d,viewTransition:h}=e,f=fr(e,Sr),{basename:p}=n.useContext(st),m=!1;if("string"==typeof c&&Hr.test(c)&&(r=c,zr))try{let e=new URL(window.location.href),t=c.startsWith("//")?new URL(e.protocol+c):new URL(c),r=N(t.pathname,p);t.origin===e.origin&&null!=r?c=r+t.search+t.hash:m=!0}catch(e){}let v=dt(c,{relative:o}),y=Gr(c,{replace:s,state:l,target:u,preventScrollReset:d,relative:o,viewTransition:h});return n.createElement("a",hr({},f,{href:r||v,onClick:m||i?a:function(e){a&&a(e),e.defaultPrevented||y(e)},ref:t,target:u}))})),Kr=n.forwardRef((function(e,t){let{"aria-current":r="page",caseSensitive:a=!1,className:o="",end:i=!1,style:s,to:l,viewTransition:u,children:c}=e,d=fr(e,Er),h=Et(l,{relative:d.relative}),f=ft(),p=n.useContext(ot),{navigator:m,basename:v}=n.useContext(st),y=null!=p&&dn(h)&&!0===u,g=m.encodeLocation?m.encodeLocation(h).pathname:h.pathname,b=f.pathname,w=p&&p.navigation&&p.navigation.location?p.navigation.location.pathname:null;a||(b=b.toLowerCase(),w=w?w.toLowerCase():null,g=g.toLowerCase()),w&&v&&(w=N(w,v)||w);const S="/"!==g&&g.endsWith("/")?g.length-1:g.length;let E,R=b===g||!i&&b.startsWith(g)&&"/"===b.charAt(S),x=null!=w&&(w===g||!i&&w.startsWith(g)&&"/"===w.charAt(g.length)),D={isActive:R,isPending:x,isTransitioning:y},C=R?r:void 0;E="function"==typeof o?o(D):[o,R?"active":null,x?"pending":null,y?"transitioning":null].filter(Boolean).join(" ");let P="function"==typeof s?s(D):s;return n.createElement(Wr,hr({},d,{"aria-current":C,className:E,ref:t,style:P,to:l,viewTransition:u}),"function"==typeof c?c(D):c)})),$r=n.forwardRef(((e,t)=>{let{fetcherKey:r,navigate:a,reloadDocument:o,replace:i,state:s,method:l=pr,action:u,onSubmit:c,relative:d,preventScrollReset:h,viewTransition:f}=e,p=fr(e,Rr),m=tn(),v=rn(u,{relative:d}),y="get"===l.toLowerCase()?"get":"post";return n.createElement("form",hr({ref:t,method:y,action:v,onSubmit:o?c:e=>{if(c&&c(e),e.defaultPrevented)return;e.preventDefault();let t=e.nativeEvent.submitter,n=(null==t?void 0:t.getAttribute("formmethod"))||l;m(t||e.currentTarget,{fetcherKey:r,method:n,navigate:a,replace:i,state:s,relative:d,preventScrollReset:h,viewTransition:f})}},p))}));function Vr(e){let{getKey:t,storageKey:r}=e;return ln({getKey:t,storageKey:r}),null}var Jr,qr;function Yr(e){let t=n.useContext(at);return t||d(!1),t}function Xr(e){let t=n.useContext(ot);return t||d(!1),t}function Gr(e,t){let{target:r,replace:a,state:o,preventScrollReset:i,relative:s,viewTransition:l}=void 0===t?{}:t,u=yt(),c=ft(),d=Et(e,{relative:s});return n.useCallback((t=>{if(function(e,t){return!(0!==e.button||t&&"_self"!==t||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e))}(t,r)){t.preventDefault();let r=void 0!==a?a:m(c)===m(d);u(e,{replace:r,state:o,preventScrollReset:i,relative:s,viewTransition:l})}}),[c,u,d,a,o,r,e,i,s,l])}function Qr(e){let t=n.useRef(yr(e)),r=n.useRef(!1),a=ft(),o=n.useMemo((()=>function(e,t){let r=yr(e);return t&&t.forEach(((e,n)=>{r.has(n)||t.getAll(n).forEach((e=>{r.append(n,e)}))})),r}(a.search,r.current?null:t.current)),[a.search]),i=yt(),s=n.useCallback(((e,t)=>{const n=yr("function"==typeof e?e(o):e);r.current=!0,i("?"+n,t)}),[i,o]);return[o,s]}(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(Jr||(Jr={})),function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"}(qr||(qr={}));let Zr=0,en=()=>"__"+String(++Zr)+"__";function tn(){let{router:e}=Yr(Jr.UseSubmit),{basename:t}=n.useContext(st),r=jt();return n.useCallback((function(n,a){void 0===a&&(a={}),function(){if("undefined"==typeof document)throw new Error("You are calling submit during the server render. Try calling submit within a `useEffect` or callback instead.")}();let{action:o,method:i,encType:s,formData:l,body:u}=function(e,t){let r,n,a,o,i;if(vr(s=e)&&"form"===s.tagName.toLowerCase()){let i=e.getAttribute("action");n=i?N(i,t):null,r=e.getAttribute("method")||pr,a=wr(e.getAttribute("enctype"))||mr,o=new FormData(e)}else if(function(e){return vr(e)&&"button"===e.tagName.toLowerCase()}(e)||function(e){return vr(e)&&"input"===e.tagName.toLowerCase()}(e)&&("submit"===e.type||"image"===e.type)){let i=e.form;if(null==i)throw new Error('Cannot submit a