diff --git a/Cargo.toml b/Cargo.toml index f8fd745..f33a426 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,8 @@ edition = "2021" dioxus-desktop = { version = "0.4" } dioxus = { version = "0.4" } dioxus-ssr = "0.4" - dioxus-router = { version = "0.4" } + slpprocess = {path = "..\\SlpProcess\\slpprocess"} ssbm_utils = {path = "..\\SlpProcess\\ssbm-utils"} @@ -34,6 +34,13 @@ polars = { version = "0.35.2", features = [ "list_count" ] } time = {version = "0.3.30", features = ["serde", "parsing", "local-offset"]} +rayon = "1.7.0" +tokio = "1.28" +futures-util = "0.3.29" +wry = "^0.28.0" +tao = "0.19.1" +counter = "0.5.7" + [profile.release] -lto = true \ No newline at end of file +lto = true diff --git a/Dioxus.toml b/Dioxus.toml index 47ff45d..4bb0a18 100644 --- a/Dioxus.toml +++ b/Dioxus.toml @@ -24,13 +24,13 @@ title = "Slippi Stats Dash" reload_html = true # which files or dirs will be watcher monitoring -watch_path = ["./src", "./assets"] +# watch_path = ["./src", "./assets"] # include `assets` in web platform [web.resource] # CSS style file -style = ["./dist/pico-1.5.9/css/pico.min.css"] +style = ["./assets/beer.min.css"] # Javascript code file script = [] @@ -40,7 +40,7 @@ script = [] # Javascript code file # serve: [dev-server] only script = [] -style = ["./dist/pico-1.5.9/css/pico.min.css"] +style = ["./assets/beer.min.css"] [bundle] -resources = ["./dist/pico-1.5.9"] \ No newline at end of file +resources = ["./dist/beer.min.css"] \ No newline at end of file diff --git a/README.md b/README.md index a5dd4a5..fef5e83 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ WIP stats app for slippi replays based off of my [stats parser](https://github.com/Walnut356/SlpProcess). -Built using Dioxus and a slightly modified PicoCSS +Built using Dioxus and a slightly modified BeerCSS + +Special shoutouts to [Waga](https://ssbmtextures.com/other-mod-types/modernized-stock-icons/) for the stock icons diff --git a/assets/Characters/Bowser/black.png b/assets/Characters/Bowser/black.png new file mode 100644 index 0000000..5d9b0c2 Binary files /dev/null and b/assets/Characters/Bowser/black.png differ diff --git a/assets/Characters/Bowser/blue.png b/assets/Characters/Bowser/blue.png new file mode 100644 index 0000000..2b8cf1a Binary files /dev/null and b/assets/Characters/Bowser/blue.png differ diff --git a/assets/Characters/Bowser/default.png b/assets/Characters/Bowser/default.png new file mode 100644 index 0000000..4451972 Binary files /dev/null and b/assets/Characters/Bowser/default.png differ diff --git a/assets/Characters/Bowser/red.png b/assets/Characters/Bowser/red.png new file mode 100644 index 0000000..834c58c Binary files /dev/null and b/assets/Characters/Bowser/red.png differ diff --git a/assets/Characters/CaptainFalcon/black.png b/assets/Characters/CaptainFalcon/black.png new file mode 100644 index 0000000..bb4fb77 Binary files /dev/null and b/assets/Characters/CaptainFalcon/black.png differ diff --git a/assets/Characters/CaptainFalcon/blue.png b/assets/Characters/CaptainFalcon/blue.png new file mode 100644 index 0000000..ef0002a Binary files /dev/null and b/assets/Characters/CaptainFalcon/blue.png differ diff --git a/assets/Characters/CaptainFalcon/default.png b/assets/Characters/CaptainFalcon/default.png new file mode 100644 index 0000000..5d57f4c Binary files /dev/null and b/assets/Characters/CaptainFalcon/default.png differ diff --git a/assets/Characters/CaptainFalcon/green.png b/assets/Characters/CaptainFalcon/green.png new file mode 100644 index 0000000..cfd7b21 Binary files /dev/null and b/assets/Characters/CaptainFalcon/green.png differ diff --git a/assets/Characters/CaptainFalcon/red.png b/assets/Characters/CaptainFalcon/red.png new file mode 100644 index 0000000..be5b8bc Binary files /dev/null and b/assets/Characters/CaptainFalcon/red.png differ diff --git a/assets/Characters/CaptainFalcon/white.png b/assets/Characters/CaptainFalcon/white.png new file mode 100644 index 0000000..2d78020 Binary files /dev/null and b/assets/Characters/CaptainFalcon/white.png differ diff --git a/assets/Characters/DonkeyKong/black.png b/assets/Characters/DonkeyKong/black.png new file mode 100644 index 0000000..d1cf09f Binary files /dev/null and b/assets/Characters/DonkeyKong/black.png differ diff --git a/assets/Characters/DonkeyKong/blue.png b/assets/Characters/DonkeyKong/blue.png new file mode 100644 index 0000000..55d884f Binary files /dev/null and b/assets/Characters/DonkeyKong/blue.png differ diff --git a/assets/Characters/DonkeyKong/default.png b/assets/Characters/DonkeyKong/default.png new file mode 100644 index 0000000..e855cc3 Binary files /dev/null and b/assets/Characters/DonkeyKong/default.png differ diff --git a/assets/Characters/DonkeyKong/green.png b/assets/Characters/DonkeyKong/green.png new file mode 100644 index 0000000..c935ae6 Binary files /dev/null and b/assets/Characters/DonkeyKong/green.png differ diff --git a/assets/Characters/DonkeyKong/red.png b/assets/Characters/DonkeyKong/red.png new file mode 100644 index 0000000..4fdfd18 Binary files /dev/null and b/assets/Characters/DonkeyKong/red.png differ diff --git a/assets/Characters/DrMario/black.png b/assets/Characters/DrMario/black.png new file mode 100644 index 0000000..e314119 Binary files /dev/null and b/assets/Characters/DrMario/black.png differ diff --git a/assets/Characters/DrMario/blue.png b/assets/Characters/DrMario/blue.png new file mode 100644 index 0000000..5f36806 Binary files /dev/null and b/assets/Characters/DrMario/blue.png differ diff --git a/assets/Characters/DrMario/default.png b/assets/Characters/DrMario/default.png new file mode 100644 index 0000000..9521dc6 Binary files /dev/null and b/assets/Characters/DrMario/default.png differ diff --git a/assets/Characters/DrMario/green.png b/assets/Characters/DrMario/green.png new file mode 100644 index 0000000..8c5f4c4 Binary files /dev/null and b/assets/Characters/DrMario/green.png differ diff --git a/assets/Characters/DrMario/red.png b/assets/Characters/DrMario/red.png new file mode 100644 index 0000000..6f2612c Binary files /dev/null and b/assets/Characters/DrMario/red.png differ diff --git a/assets/Characters/Falco/blue.png b/assets/Characters/Falco/blue.png new file mode 100644 index 0000000..7801641 Binary files /dev/null and b/assets/Characters/Falco/blue.png differ diff --git a/assets/Characters/Falco/default.png b/assets/Characters/Falco/default.png new file mode 100644 index 0000000..52b896f Binary files /dev/null and b/assets/Characters/Falco/default.png differ diff --git a/assets/Characters/Falco/green.png b/assets/Characters/Falco/green.png new file mode 100644 index 0000000..4cffc72 Binary files /dev/null and b/assets/Characters/Falco/green.png differ diff --git a/assets/Characters/Falco/red.png b/assets/Characters/Falco/red.png new file mode 100644 index 0000000..710d342 Binary files /dev/null and b/assets/Characters/Falco/red.png differ diff --git a/assets/Characters/Fox/blue.png b/assets/Characters/Fox/blue.png new file mode 100644 index 0000000..02230b5 Binary files /dev/null and b/assets/Characters/Fox/blue.png differ diff --git a/assets/Characters/Fox/default.png b/assets/Characters/Fox/default.png new file mode 100644 index 0000000..c6530eb Binary files /dev/null and b/assets/Characters/Fox/default.png differ diff --git a/assets/Characters/Fox/green.png b/assets/Characters/Fox/green.png new file mode 100644 index 0000000..a954160 Binary files /dev/null and b/assets/Characters/Fox/green.png differ diff --git a/assets/Characters/Fox/red.png b/assets/Characters/Fox/red.png new file mode 100644 index 0000000..cda7513 Binary files /dev/null and b/assets/Characters/Fox/red.png differ diff --git a/assets/Characters/GameAndWatch/blue.png b/assets/Characters/GameAndWatch/blue.png new file mode 100644 index 0000000..02c3ecd Binary files /dev/null and b/assets/Characters/GameAndWatch/blue.png differ diff --git a/assets/Characters/GameAndWatch/default.png b/assets/Characters/GameAndWatch/default.png new file mode 100644 index 0000000..9ec47c2 Binary files /dev/null and b/assets/Characters/GameAndWatch/default.png differ diff --git a/assets/Characters/GameAndWatch/green.png b/assets/Characters/GameAndWatch/green.png new file mode 100644 index 0000000..32355a9 Binary files /dev/null and b/assets/Characters/GameAndWatch/green.png differ diff --git a/assets/Characters/GameAndWatch/red.png b/assets/Characters/GameAndWatch/red.png new file mode 100644 index 0000000..13b4dae Binary files /dev/null and b/assets/Characters/GameAndWatch/red.png differ diff --git a/assets/Characters/Ganondorf/blue.png b/assets/Characters/Ganondorf/blue.png new file mode 100644 index 0000000..124e93f Binary files /dev/null and b/assets/Characters/Ganondorf/blue.png differ diff --git a/assets/Characters/Ganondorf/default.png b/assets/Characters/Ganondorf/default.png new file mode 100644 index 0000000..56f7c5e Binary files /dev/null and b/assets/Characters/Ganondorf/default.png differ diff --git a/assets/Characters/Ganondorf/green.png b/assets/Characters/Ganondorf/green.png new file mode 100644 index 0000000..6b77f7a Binary files /dev/null and b/assets/Characters/Ganondorf/green.png differ diff --git a/assets/Characters/Ganondorf/purple.png b/assets/Characters/Ganondorf/purple.png new file mode 100644 index 0000000..da8ec4e Binary files /dev/null and b/assets/Characters/Ganondorf/purple.png differ diff --git a/assets/Characters/Ganondorf/red.png b/assets/Characters/Ganondorf/red.png new file mode 100644 index 0000000..20225ef Binary files /dev/null and b/assets/Characters/Ganondorf/red.png differ diff --git a/assets/Characters/IceClimbers/default.png b/assets/Characters/IceClimbers/default.png new file mode 100644 index 0000000..0ef19e1 Binary files /dev/null and b/assets/Characters/IceClimbers/default.png differ diff --git a/assets/Characters/IceClimbers/green.png b/assets/Characters/IceClimbers/green.png new file mode 100644 index 0000000..1d68a77 Binary files /dev/null and b/assets/Characters/IceClimbers/green.png differ diff --git a/assets/Characters/IceClimbers/orange.png b/assets/Characters/IceClimbers/orange.png new file mode 100644 index 0000000..db96b73 Binary files /dev/null and b/assets/Characters/IceClimbers/orange.png differ diff --git a/assets/Characters/IceClimbers/red.png b/assets/Characters/IceClimbers/red.png new file mode 100644 index 0000000..321a82e Binary files /dev/null and b/assets/Characters/IceClimbers/red.png differ diff --git a/assets/Characters/Jigglypuff/bow.png b/assets/Characters/Jigglypuff/bow.png new file mode 100644 index 0000000..b412351 Binary files /dev/null and b/assets/Characters/Jigglypuff/bow.png differ diff --git a/assets/Characters/Jigglypuff/crown.png b/assets/Characters/Jigglypuff/crown.png new file mode 100644 index 0000000..033c0f4 Binary files /dev/null and b/assets/Characters/Jigglypuff/crown.png differ diff --git a/assets/Characters/Jigglypuff/default.png b/assets/Characters/Jigglypuff/default.png new file mode 100644 index 0000000..b711a74 Binary files /dev/null and b/assets/Characters/Jigglypuff/default.png differ diff --git a/assets/Characters/Jigglypuff/headband.png b/assets/Characters/Jigglypuff/headband.png new file mode 100644 index 0000000..fe83778 Binary files /dev/null and b/assets/Characters/Jigglypuff/headband.png differ diff --git a/assets/Characters/Jigglypuff/rose.png b/assets/Characters/Jigglypuff/rose.png new file mode 100644 index 0000000..09d4fbe Binary files /dev/null and b/assets/Characters/Jigglypuff/rose.png differ diff --git a/assets/Characters/Kirby/blue.png b/assets/Characters/Kirby/blue.png new file mode 100644 index 0000000..a6ab284 Binary files /dev/null and b/assets/Characters/Kirby/blue.png differ diff --git a/assets/Characters/Kirby/default.png b/assets/Characters/Kirby/default.png new file mode 100644 index 0000000..9e314fa Binary files /dev/null and b/assets/Characters/Kirby/default.png differ diff --git a/assets/Characters/Kirby/green.png b/assets/Characters/Kirby/green.png new file mode 100644 index 0000000..58f1762 Binary files /dev/null and b/assets/Characters/Kirby/green.png differ diff --git a/assets/Characters/Kirby/red.png b/assets/Characters/Kirby/red.png new file mode 100644 index 0000000..99d3567 Binary files /dev/null and b/assets/Characters/Kirby/red.png differ diff --git a/assets/Characters/Kirby/white.png b/assets/Characters/Kirby/white.png new file mode 100644 index 0000000..c833f88 Binary files /dev/null and b/assets/Characters/Kirby/white.png differ diff --git a/assets/Characters/Kirby/yellow.png b/assets/Characters/Kirby/yellow.png new file mode 100644 index 0000000..d8c1ba3 Binary files /dev/null and b/assets/Characters/Kirby/yellow.png differ diff --git a/assets/Characters/Link/black.png b/assets/Characters/Link/black.png new file mode 100644 index 0000000..af85abe Binary files /dev/null and b/assets/Characters/Link/black.png differ diff --git a/assets/Characters/Link/blue.png b/assets/Characters/Link/blue.png new file mode 100644 index 0000000..c004c0d Binary files /dev/null and b/assets/Characters/Link/blue.png differ diff --git a/assets/Characters/Link/default.png b/assets/Characters/Link/default.png new file mode 100644 index 0000000..3f1dec4 Binary files /dev/null and b/assets/Characters/Link/default.png differ diff --git a/assets/Characters/Link/red.png b/assets/Characters/Link/red.png new file mode 100644 index 0000000..c4db42a Binary files /dev/null and b/assets/Characters/Link/red.png differ diff --git a/assets/Characters/Link/white.png b/assets/Characters/Link/white.png new file mode 100644 index 0000000..49344e0 Binary files /dev/null and b/assets/Characters/Link/white.png differ diff --git a/assets/Characters/Luigi/blue.png b/assets/Characters/Luigi/blue.png new file mode 100644 index 0000000..0288fed Binary files /dev/null and b/assets/Characters/Luigi/blue.png differ diff --git a/assets/Characters/Luigi/default.png b/assets/Characters/Luigi/default.png new file mode 100644 index 0000000..c5e75e6 Binary files /dev/null and b/assets/Characters/Luigi/default.png differ diff --git a/assets/Characters/Luigi/pink.png b/assets/Characters/Luigi/pink.png new file mode 100644 index 0000000..5007b4a Binary files /dev/null and b/assets/Characters/Luigi/pink.png differ diff --git a/assets/Characters/Luigi/white.png b/assets/Characters/Luigi/white.png new file mode 100644 index 0000000..9a990d9 Binary files /dev/null and b/assets/Characters/Luigi/white.png differ diff --git a/assets/Characters/Mario/black.png b/assets/Characters/Mario/black.png new file mode 100644 index 0000000..645bf5f Binary files /dev/null and b/assets/Characters/Mario/black.png differ diff --git a/assets/Characters/Mario/blue.png b/assets/Characters/Mario/blue.png new file mode 100644 index 0000000..061afc0 Binary files /dev/null and b/assets/Characters/Mario/blue.png differ diff --git a/assets/Characters/Mario/default.png b/assets/Characters/Mario/default.png new file mode 100644 index 0000000..7959970 Binary files /dev/null and b/assets/Characters/Mario/default.png differ diff --git a/assets/Characters/Mario/green.png b/assets/Characters/Mario/green.png new file mode 100644 index 0000000..4cebfd2 Binary files /dev/null and b/assets/Characters/Mario/green.png differ diff --git a/assets/Characters/Mario/yellow.png b/assets/Characters/Mario/yellow.png new file mode 100644 index 0000000..68641bd Binary files /dev/null and b/assets/Characters/Mario/yellow.png differ diff --git a/assets/Characters/Marth/black.png b/assets/Characters/Marth/black.png new file mode 100644 index 0000000..6b06153 Binary files /dev/null and b/assets/Characters/Marth/black.png differ diff --git a/assets/Characters/Marth/default.png b/assets/Characters/Marth/default.png new file mode 100644 index 0000000..03f46a1 Binary files /dev/null and b/assets/Characters/Marth/default.png differ diff --git a/assets/Characters/Marth/green.png b/assets/Characters/Marth/green.png new file mode 100644 index 0000000..7297822 Binary files /dev/null and b/assets/Characters/Marth/green.png differ diff --git a/assets/Characters/Marth/red.png b/assets/Characters/Marth/red.png new file mode 100644 index 0000000..87150d8 Binary files /dev/null and b/assets/Characters/Marth/red.png differ diff --git a/assets/Characters/Marth/white.png b/assets/Characters/Marth/white.png new file mode 100644 index 0000000..1bc5d5a Binary files /dev/null and b/assets/Characters/Marth/white.png differ diff --git a/assets/Characters/Mewtwo/blue.png b/assets/Characters/Mewtwo/blue.png new file mode 100644 index 0000000..e510399 Binary files /dev/null and b/assets/Characters/Mewtwo/blue.png differ diff --git a/assets/Characters/Mewtwo/default.png b/assets/Characters/Mewtwo/default.png new file mode 100644 index 0000000..8f33854 Binary files /dev/null and b/assets/Characters/Mewtwo/default.png differ diff --git a/assets/Characters/Mewtwo/green.png b/assets/Characters/Mewtwo/green.png new file mode 100644 index 0000000..4dc34f5 Binary files /dev/null and b/assets/Characters/Mewtwo/green.png differ diff --git a/assets/Characters/Mewtwo/red.png b/assets/Characters/Mewtwo/red.png new file mode 100644 index 0000000..4341eba Binary files /dev/null and b/assets/Characters/Mewtwo/red.png differ diff --git a/assets/Characters/Ness/blue.png b/assets/Characters/Ness/blue.png new file mode 100644 index 0000000..79b8211 Binary files /dev/null and b/assets/Characters/Ness/blue.png differ diff --git a/assets/Characters/Ness/default.png b/assets/Characters/Ness/default.png new file mode 100644 index 0000000..8b56aec Binary files /dev/null and b/assets/Characters/Ness/default.png differ diff --git a/assets/Characters/Ness/green.png b/assets/Characters/Ness/green.png new file mode 100644 index 0000000..8bf9173 Binary files /dev/null and b/assets/Characters/Ness/green.png differ diff --git a/assets/Characters/Ness/yellow.png b/assets/Characters/Ness/yellow.png new file mode 100644 index 0000000..75c28d9 Binary files /dev/null and b/assets/Characters/Ness/yellow.png differ diff --git a/assets/Characters/Peach/blue.png b/assets/Characters/Peach/blue.png new file mode 100644 index 0000000..c7aa08b Binary files /dev/null and b/assets/Characters/Peach/blue.png differ diff --git a/assets/Characters/Peach/daisy.png b/assets/Characters/Peach/daisy.png new file mode 100644 index 0000000..4cd747d Binary files /dev/null and b/assets/Characters/Peach/daisy.png differ diff --git a/assets/Characters/Peach/default.png b/assets/Characters/Peach/default.png new file mode 100644 index 0000000..bd836d0 Binary files /dev/null and b/assets/Characters/Peach/default.png differ diff --git a/assets/Characters/Peach/green.png b/assets/Characters/Peach/green.png new file mode 100644 index 0000000..d78a77d Binary files /dev/null and b/assets/Characters/Peach/green.png differ diff --git a/assets/Characters/Peach/white.png b/assets/Characters/Peach/white.png new file mode 100644 index 0000000..4361faf Binary files /dev/null and b/assets/Characters/Peach/white.png differ diff --git a/assets/Characters/Pichu/backpack.png b/assets/Characters/Pichu/backpack.png new file mode 100644 index 0000000..51ce570 Binary files /dev/null and b/assets/Characters/Pichu/backpack.png differ diff --git a/assets/Characters/Pichu/bandana.png b/assets/Characters/Pichu/bandana.png new file mode 100644 index 0000000..5e0fbda Binary files /dev/null and b/assets/Characters/Pichu/bandana.png differ diff --git a/assets/Characters/Pichu/default.png b/assets/Characters/Pichu/default.png new file mode 100644 index 0000000..c78d6c2 Binary files /dev/null and b/assets/Characters/Pichu/default.png differ diff --git a/assets/Characters/Pichu/goggles.png b/assets/Characters/Pichu/goggles.png new file mode 100644 index 0000000..6d6fe5a Binary files /dev/null and b/assets/Characters/Pichu/goggles.png differ diff --git a/assets/Characters/Pikachu/cap.png b/assets/Characters/Pikachu/cap.png new file mode 100644 index 0000000..f406b86 Binary files /dev/null and b/assets/Characters/Pikachu/cap.png differ diff --git a/assets/Characters/Pikachu/cowboy.png b/assets/Characters/Pikachu/cowboy.png new file mode 100644 index 0000000..cff8d75 Binary files /dev/null and b/assets/Characters/Pikachu/cowboy.png differ diff --git a/assets/Characters/Pikachu/default.png b/assets/Characters/Pikachu/default.png new file mode 100644 index 0000000..3127da1 Binary files /dev/null and b/assets/Characters/Pikachu/default.png differ diff --git a/assets/Characters/Pikachu/party_hat.png b/assets/Characters/Pikachu/party_hat.png new file mode 100644 index 0000000..3aba0ed Binary files /dev/null and b/assets/Characters/Pikachu/party_hat.png differ diff --git a/assets/Characters/Roy/blue.png b/assets/Characters/Roy/blue.png new file mode 100644 index 0000000..3342db4 Binary files /dev/null and b/assets/Characters/Roy/blue.png differ diff --git a/assets/Characters/Roy/default.png b/assets/Characters/Roy/default.png new file mode 100644 index 0000000..cefd41f Binary files /dev/null and b/assets/Characters/Roy/default.png differ diff --git a/assets/Characters/Roy/gold.png b/assets/Characters/Roy/gold.png new file mode 100644 index 0000000..eb37365 Binary files /dev/null and b/assets/Characters/Roy/gold.png differ diff --git a/assets/Characters/Roy/green.png b/assets/Characters/Roy/green.png new file mode 100644 index 0000000..0efc632 Binary files /dev/null and b/assets/Characters/Roy/green.png differ diff --git a/assets/Characters/Roy/red.png b/assets/Characters/Roy/red.png new file mode 100644 index 0000000..4bb6805 Binary files /dev/null and b/assets/Characters/Roy/red.png differ diff --git a/assets/Characters/Samus/black.png b/assets/Characters/Samus/black.png new file mode 100644 index 0000000..4da553b Binary files /dev/null and b/assets/Characters/Samus/black.png differ diff --git a/assets/Characters/Samus/default.png b/assets/Characters/Samus/default.png new file mode 100644 index 0000000..b73fcd5 Binary files /dev/null and b/assets/Characters/Samus/default.png differ diff --git a/assets/Characters/Samus/green.png b/assets/Characters/Samus/green.png new file mode 100644 index 0000000..5c0e6e9 Binary files /dev/null and b/assets/Characters/Samus/green.png differ diff --git a/assets/Characters/Samus/pink.png b/assets/Characters/Samus/pink.png new file mode 100644 index 0000000..4e0179b Binary files /dev/null and b/assets/Characters/Samus/pink.png differ diff --git a/assets/Characters/Samus/purple.png b/assets/Characters/Samus/purple.png new file mode 100644 index 0000000..cc2d6f7 Binary files /dev/null and b/assets/Characters/Samus/purple.png differ diff --git a/assets/Characters/Sheik/blue.png b/assets/Characters/Sheik/blue.png new file mode 100644 index 0000000..9cd4c25 Binary files /dev/null and b/assets/Characters/Sheik/blue.png differ diff --git a/assets/Characters/Sheik/default.png b/assets/Characters/Sheik/default.png new file mode 100644 index 0000000..a369953 Binary files /dev/null and b/assets/Characters/Sheik/default.png differ diff --git a/assets/Characters/Sheik/green.png b/assets/Characters/Sheik/green.png new file mode 100644 index 0000000..76a0c86 Binary files /dev/null and b/assets/Characters/Sheik/green.png differ diff --git a/assets/Characters/Sheik/red.png b/assets/Characters/Sheik/red.png new file mode 100644 index 0000000..b9c65d3 Binary files /dev/null and b/assets/Characters/Sheik/red.png differ diff --git a/assets/Characters/Sheik/white.png b/assets/Characters/Sheik/white.png new file mode 100644 index 0000000..89129ae Binary files /dev/null and b/assets/Characters/Sheik/white.png differ diff --git a/assets/Characters/Yoshi/blue.png b/assets/Characters/Yoshi/blue.png new file mode 100644 index 0000000..4c47593 Binary files /dev/null and b/assets/Characters/Yoshi/blue.png differ diff --git a/assets/Characters/Yoshi/cyan.png b/assets/Characters/Yoshi/cyan.png new file mode 100644 index 0000000..22ce2d4 Binary files /dev/null and b/assets/Characters/Yoshi/cyan.png differ diff --git a/assets/Characters/Yoshi/default.png b/assets/Characters/Yoshi/default.png new file mode 100644 index 0000000..60a96ec Binary files /dev/null and b/assets/Characters/Yoshi/default.png differ diff --git a/assets/Characters/Yoshi/pink.png b/assets/Characters/Yoshi/pink.png new file mode 100644 index 0000000..944d445 Binary files /dev/null and b/assets/Characters/Yoshi/pink.png differ diff --git a/assets/Characters/Yoshi/red.png b/assets/Characters/Yoshi/red.png new file mode 100644 index 0000000..caf06aa Binary files /dev/null and b/assets/Characters/Yoshi/red.png differ diff --git a/assets/Characters/Yoshi/yellow.png b/assets/Characters/Yoshi/yellow.png new file mode 100644 index 0000000..660c893 Binary files /dev/null and b/assets/Characters/Yoshi/yellow.png differ diff --git a/assets/Characters/YoungLink/black.png b/assets/Characters/YoungLink/black.png new file mode 100644 index 0000000..83fffc5 Binary files /dev/null and b/assets/Characters/YoungLink/black.png differ diff --git a/assets/Characters/YoungLink/blue.png b/assets/Characters/YoungLink/blue.png new file mode 100644 index 0000000..0f09a4d Binary files /dev/null and b/assets/Characters/YoungLink/blue.png differ diff --git a/assets/Characters/YoungLink/default.png b/assets/Characters/YoungLink/default.png new file mode 100644 index 0000000..e5cea42 Binary files /dev/null and b/assets/Characters/YoungLink/default.png differ diff --git a/assets/Characters/YoungLink/red.png b/assets/Characters/YoungLink/red.png new file mode 100644 index 0000000..7fc0d0d Binary files /dev/null and b/assets/Characters/YoungLink/red.png differ diff --git a/assets/Characters/YoungLink/white.png b/assets/Characters/YoungLink/white.png new file mode 100644 index 0000000..8d48ddd Binary files /dev/null and b/assets/Characters/YoungLink/white.png differ diff --git a/assets/Characters/Zelda/blue.png b/assets/Characters/Zelda/blue.png new file mode 100644 index 0000000..7124215 Binary files /dev/null and b/assets/Characters/Zelda/blue.png differ diff --git a/assets/Characters/Zelda/default.png b/assets/Characters/Zelda/default.png new file mode 100644 index 0000000..5d9dff3 Binary files /dev/null and b/assets/Characters/Zelda/default.png differ diff --git a/assets/Characters/Zelda/green.png b/assets/Characters/Zelda/green.png new file mode 100644 index 0000000..1851b18 Binary files /dev/null and b/assets/Characters/Zelda/green.png differ diff --git a/assets/Characters/Zelda/red.png b/assets/Characters/Zelda/red.png new file mode 100644 index 0000000..6b06b32 Binary files /dev/null and b/assets/Characters/Zelda/red.png differ diff --git a/assets/Characters/Zelda/white.png b/assets/Characters/Zelda/white.png new file mode 100644 index 0000000..50d78b0 Binary files /dev/null and b/assets/Characters/Zelda/white.png differ diff --git a/assets/Stages/BATTLEFIELD.png b/assets/Stages/BATTLEFIELD.png new file mode 100644 index 0000000..1e7c193 Binary files /dev/null and b/assets/Stages/BATTLEFIELD.png differ diff --git a/assets/Stages/DREAM_LAND_N64.png b/assets/Stages/DREAM_LAND_N64.png new file mode 100644 index 0000000..f7b1e3f Binary files /dev/null and b/assets/Stages/DREAM_LAND_N64.png differ diff --git a/assets/Stages/FINAL_DESTINATION.png b/assets/Stages/FINAL_DESTINATION.png new file mode 100644 index 0000000..2e6861c Binary files /dev/null and b/assets/Stages/FINAL_DESTINATION.png differ diff --git a/assets/Stages/FOUNTAIN_OF_DREAMS.png b/assets/Stages/FOUNTAIN_OF_DREAMS.png new file mode 100644 index 0000000..92b22a5 Binary files /dev/null and b/assets/Stages/FOUNTAIN_OF_DREAMS.png differ diff --git a/assets/Stages/POKEMON_STADIUM.png b/assets/Stages/POKEMON_STADIUM.png new file mode 100644 index 0000000..738f866 Binary files /dev/null and b/assets/Stages/POKEMON_STADIUM.png differ diff --git a/assets/Stages/YOSHIS_STORY.png b/assets/Stages/YOSHIS_STORY.png new file mode 100644 index 0000000..8778580 Binary files /dev/null and b/assets/Stages/YOSHIS_STORY.png differ diff --git a/assets/beer.min.css b/assets/beer.min.css new file mode 100644 index 0000000..2574edf --- /dev/null +++ b/assets/beer.min.css @@ -0,0 +1,4868 @@ +:root { + --size: 16px; + --font: Inter, Roboto, "Helvetica Neue", "Arial Nova", "Nimbus Sans", Arial, sans-serif; + --font-icon: "Material Symbols Outlined"; + --speed1: .1s; + --speed2: .2s; + --speed3: .3s; + --speed4: .4s +} + +:root, +body.light { + --primary: #6750a4; + --on-primary: #ffffff; + --primary-container: #e9ddff; + --on-primary-container: #22005d; + --secondary: #625b71; + --on-secondary: #ffffff; + --secondary-container: #e8def8; + --on-secondary-container: #1e192b; + --tertiary: #7e5260; + --on-tertiary: #ffffff; + --tertiary-container: #ffd9e3; + --on-tertiary-container: #31101d; + --error: #ba1a1a; + --on-error: #ffffff; + --error-container: #ffdad6; + --on-error-container: #410002; + --background: #fffbff; + --on-background: #1c1b1e; + --surface: #fdf8fd; + --on-surface: #1c1b1e; + --surface-variant: #e7e0eb; + --on-surface-variant: #49454e; + --outline: #7a757f; + --outline-variant: #cac4cf; + --shadow: #000000; + --scrim: #000000; + --inverse-surface: #313033; + --inverse-on-surface: #f4eff4; + --inverse-primary: #cfbcff; + --surface-dim: #ddd8dd; + --surface-bright: #fdf8fd; + --surface-container-lowest: #ffffff; + --surface-container-low: #f7f2f7; + --surface-container: #f2ecf1; + --surface-container-high: #ece7eb; + --surface-container-highest: #e6e1e6; + --overlay: rgb(0 0 0 / .5); + --active: rgb(0 0 0 / .1); + --elevate1: 0 .125rem .125rem 0 rgb(0 0 0 / .32); + --elevate2: 0 .25rem .5rem 0 rgb(0 0 0 / .4); + --elevate3: 0 .375rem .75rem 0 rgb(0 0 0 / .48) +} + +body.dark { + --primary: #ffb59a; + --on-primary: #5b1b00; + --primary-container: #7b2e0d; + --on-primary-container: #ffdbcf; + --secondary: #e7beaf; + --on-secondary: #442a20; + --secondary-container: #5d4035; + --on-secondary-container: #ffdbcf; + --tertiary: #d5c68e; + --on-tertiary: #393005; + --tertiary-container: #50471a; + --on-tertiary-container: #f2e2a8; + --error: #ffb4ab; + --on-error: #690005; + --error-container: #93000a; + --on-error-container: #ffb4ab; + --background: #201a18; + --on-background: #ede0dc; + --surface: #181210; + --on-surface: #ede0dc; + --surface-variant: #53433e; + --on-surface-variant: #d8c2bb; + --outline: #a08d86; + --outline-variant: #53433e; + --shadow: #000000; + --scrim: #000000; + --inverse-surface: #ede0dc; + --inverse-on-surface: #362f2c; + --inverse-primary: #9a4522; + --surface-dim: #181210; + --surface-bright: #3f3835; + --surface-container-lowest: #120d0b; + --surface-container-low: #201a18; + --surface-container: #251e1c; + --surface-container-high: #2f2826; + --surface-container-highest: #3b3331; + --overlay: rgb(0 0 0 / .5); + --active: rgb(255 255 255 / .2); + --elevate1: 0 .125rem .125rem 0 rgb(0 0 0 / .32); + --elevate2: 0 .25rem .5rem 0 rgb(0 0 0 / .4); + --elevate3: 0 .375rem .75rem 0 rgb(0 0 0 / .48) +} + +@font-face { + font-family: Material Symbols Outlined; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(material-symbols-outlined.woff2) format("woff2"), url(https://cdn.jsdelivr.net/npm/beercss@3.4.10/dist/cdn/material-symbols-outlined.woff2) format("woff2") +} + +@font-face { + font-family: Material Symbols Rounded; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(material-symbols-rounded.woff2) format("woff2"), url(https://cdn.jsdelivr.net/npm/beercss@3.4.10/dist/cdn/material-symbols-rounded.woff2) format("woff2") +} + +@font-face { + font-family: Material Symbols Sharp; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(material-symbols-sharp.woff2) format("woff2"), url(https://cdn.jsdelivr.net/npm/beercss@3.4.10/dist/cdn/material-symbols-sharp.woff2) format("woff2") +} + +* { + -webkit-tap-highlight-color: transparent; + position: relative; + vertical-align: middle; + color: inherit; + margin: 0; + padding: 0; + border-radius: inherit; + box-sizing: border-box +} + +body { + color: var(--on-surface); + background-color: var(--surface); + overflow-x: hidden +} + +label { + font-size: .75rem; + vertical-align: baseline +} + +a, +b, +i, +span, +strong { + vertical-align: bottom +} + +a, +button, +.button { + cursor: pointer; + text-decoration: none; + display: inline-flex; + align-items: center; + border: none; + font-family: inherit; + outline: inherit; + justify-content: center +} + +a, +button, +.button, +i, +label { + user-select: none +} + +body *::-webkit-scrollbar, +body *::-webkit-scrollbar-thumb, +body *::-webkit-scrollbar-button { + background: none; + inline-size: .75rem; + block-size: .75rem +} + +body *:is(:hover, :focus)::-webkit-scrollbar-thumb { + background: var(--outline); + border-radius: 1rem +} + +pre, +code { + direction: ltr +} + +.primary { + background-color: var(--primary) !important; + color: var(--on-primary) !important +} + +.primary-text { + color: var(--primary) !important +} + +.primary-border { + border-color: var(--primary) !important +} + +.primary-container { + background-color: var(--primary-container) !important; + color: var(--on-primary-container) !important +} + +.secondary { + background-color: var(--secondary) !important; + color: var(--on-secondary) !important +} + +.secondary-text { + color: var(--secondary) !important +} + +.secondary-border { + border-color: var(--secondary) !important +} + +.secondary-container { + background-color: var(--secondary-container) !important; + color: var(--on-secondary-container) !important +} + +.tertiary { + background-color: var(--tertiary) !important; + color: var(--on-tertiary) !important +} + +.tertiary-text { + color: var(--tertiary) !important +} + +.tertiary-border { + border-color: var(--tertiary) !important +} + +.tertiary-container { + background-color: var(--tertiary-container) !important; + color: var(--on-tertiary-container) !important +} + +.error { + background-color: var(--error) !important; + color: var(--on-error) !important +} + +.error-text { + color: var(--error) !important +} + +.error-border { + border-color: var(--error) !important +} + +.error-container { + background-color: var(--error-container) !important; + color: var(--on-error-container) !important +} + +.background { + background-color: var(--background) !important; + color: var(--on-background) !important +} + +.surface, +.surface-dim, +.surface-bright, +.surface-container-lowest, +.surface-container-low, +.surface-container, +.surface-container-high, +.surface-container-highest { + background-color: var(--surface) !important; + color: var(--on-surface) !important +} + +.surface-variant { + background-color: var(--surface-variant) !important; + color: var(--on-surface-variant) !important +} + +.inverse-surface { + background-color: var(--inverse-surface); + color: var(--inverse-on-surface) +} + +.inverse-primary { + background-color: var(--inverse-primary); + color: var(--primary) +} + +.inverse-primary-text { + color: var(--inverse-primary) !important +} + +.inverse-primary-border { + border-color: var(--inverse-primary) !important +} + +.surface-dim { + background-color: var(--surface-dim) !important +} + +.surface-bright { + background-color: var(--surface-bright) !important +} + +.surface-container-lowest { + background-color: var(--surface-container-lowest) !important +} + +.surface-container-low { + background-color: var(--surface-container-low) !important +} + +.surface-container { + background-color: var(--surface-container) !important +} + +.surface-container-high { + background-color: var(--surface-container-high) !important +} + +.surface-container-highest { + background-color: var(--surface-container-highest) !important +} + +.surface-container-low { + background-color: var(--surface-container-low) !important +} + +.black { + background-color: #000 !important +} + +.black-border { + border-color: #000 !important +} + +.black-text { + color: #000 !important +} + +.white { + background-color: #fff !important +} + +.white-border { + border-color: #fff !important +} + +.white-text { + color: #fff !important +} + +.transparent { + background-color: transparent !important; + box-shadow: none !important; + color: inherit !important +} + +.transparent-border { + border-color: transparent !important +} + +.transparent-text { + color: transparent !important +} + +.fill:not(i) { + background-color: var(--surface-variant) !important; + color: var(--on-surface-variant) !important +} + +.middle-align { + display: flex; + align-items: center !important +} + +.bottom-align { + display: flex; + align-items: flex-end !important +} + +.top-align { + display: flex; + align-items: flex-start !important +} + +.left-align { + text-align: start; + justify-content: flex-start !important +} + +.right-align { + text-align: end; + justify-content: flex-end !important +} + +.center-align { + text-align: center; + justify-content: center !important +} + +.red, +.red6 { + background-color: #f44336 !important +} + +.red-border { + border-color: #f44336 !important +} + +.red-text { + color: #f44336 !important +} + +.red1 { + background-color: #ffebee !important +} + +.red2 { + background-color: #ffcdd2 !important +} + +.red3 { + background-color: #ef9a9a !important +} + +.red4 { + background-color: #e57373 !important +} + +.red5 { + background-color: #ef5350 !important +} + +.red7 { + background-color: #e53935 !important +} + +.red8 { + background-color: #d32f2f !important +} + +.red9 { + background-color: #c62828 !important +} + +.red10 { + background-color: #b71c1c !important +} + +.pink, +.pink6 { + background-color: #e91e63 !important +} + +.pink-border { + border-color: #e91e63 !important +} + +.pink-text { + color: #e91e63 !important +} + +.pink1 { + background-color: #fce4ec !important +} + +.pink2 { + background-color: #f8bbd0 !important +} + +.pink3 { + background-color: #f48fb1 !important +} + +.pink4 { + background-color: #f06292 !important +} + +.pink5 { + background-color: #ec407a !important +} + +.pink7 { + background-color: #d81b60 !important +} + +.pink8 { + background-color: #c2185b !important +} + +.pink9 { + background-color: #ad1457 !important +} + +.pink10 { + background-color: #880e4f !important +} + +.purple, +.purple6 { + background-color: #9c27b0 !important +} + +.purple-border { + border-color: #9c27b0 !important +} + +.purple-text { + color: #9c27b0 !important +} + +.purple1 { + background-color: #f3e5f5 !important +} + +.purple2 { + background-color: #e1bee7 !important +} + +.purple3 { + background-color: #ce93d8 !important +} + +.purple4 { + background-color: #ba68c8 !important +} + +.purple5 { + background-color: #ab47bc !important +} + +.purple7 { + background-color: #8e24aa !important +} + +.purple8 { + background-color: #7b1fa2 !important +} + +.purple9 { + background-color: #6a1b9a !important +} + +.purple10 { + background-color: #4a148c !important +} + +.deep-purple, +.deep-purple6 { + background-color: #673ab7 !important +} + +.deep-purple-border { + border-color: #673ab7 !important +} + +.deep-purple-text { + color: #673ab7 !important +} + +.deep-purple1 { + background-color: #ede7f6 !important +} + +.deep-purple2 { + background-color: #d1c4e9 !important +} + +.deep-purple3 { + background-color: #b39ddb !important +} + +.deep-purple4 { + background-color: #9575cd !important +} + +.deep-purple5 { + background-color: #7e57c2 !important +} + +.deep-purple7 { + background-color: #5e35b1 !important +} + +.deep-purple8 { + background-color: #512da8 !important +} + +.deep-purple9 { + background-color: #4527a0 !important +} + +.deep-purple10 { + background-color: #311b92 !important +} + +.indigo, +.indigo6 { + background-color: #3f51b5 !important +} + +.indigo-border { + border-color: #3f51b5 !important +} + +.indigo-text { + color: #3f51b5 !important +} + +.indigo1 { + background-color: #e8eaf6 !important +} + +.indigo2 { + background-color: #c5cae9 !important +} + +.indigo3 { + background-color: #9fa8da !important +} + +.indigo4 { + background-color: #7986cb !important +} + +.indigo5 { + background-color: #5c6bc0 !important +} + +.indigo7 { + background-color: #3949ab !important +} + +.indigo8 { + background-color: #303f9f !important +} + +.indigo9 { + background-color: #283593 !important +} + +.indigo10 { + background-color: #1a237e !important +} + +.blue, +.blue6 { + background-color: #2196f3 !important +} + +.blue-border { + border-color: #2196f3 !important +} + +.blue-text { + color: #2196f3 !important +} + +.blue1 { + background-color: #e3f2fd !important +} + +.blue2 { + background-color: #bbdefb !important +} + +.blue3 { + background-color: #90caf9 !important +} + +.blue4 { + background-color: #64b5f6 !important +} + +.blue5 { + background-color: #42a5f5 !important +} + +.blue7 { + background-color: #1e88e5 !important +} + +.blue8 { + background-color: #1976d2 !important +} + +.blue9 { + background-color: #1565c0 !important +} + +.blue10 { + background-color: #0d47a1 !important +} + +.light-blue, +.light-blue6 { + background-color: #03a9f4 !important +} + +.light-blue-border { + border-color: #03a9f4 !important +} + +.light-blue-text { + color: #03a9f4 !important +} + +.light-blue1 { + background-color: #e1f5fe !important +} + +.light-blue2 { + background-color: #b3e5fc !important +} + +.light-blue3 { + background-color: #81d4fa !important +} + +.light-blue4 { + background-color: #4fc3f7 !important +} + +.light-blue5 { + background-color: #29b6f6 !important +} + +.light-blue7 { + background-color: #039be5 !important +} + +.light-blue8 { + background-color: #0288d1 !important +} + +.light-blue9 { + background-color: #0277bd !important +} + +.light-blue10 { + background-color: #01579b !important +} + +.cyan, +.cyan6 { + background-color: #00bcd4 !important +} + +.cyan-border { + border-color: #00bcd4 !important +} + +.cyan-text { + color: #00bcd4 !important +} + +.cyan1 { + background-color: #e0f7fa !important +} + +.cyan2 { + background-color: #b2ebf2 !important +} + +.cyan3 { + background-color: #80deea !important +} + +.cyan4 { + background-color: #4dd0e1 !important +} + +.cyan5 { + background-color: #26c6da !important +} + +.cyan7 { + background-color: #00acc1 !important +} + +.cyan8 { + background-color: #0097a7 !important +} + +.cyan9 { + background-color: #00838f !important +} + +.cyan10 { + background-color: #006064 !important +} + +.teal, +.teal6 { + background-color: #009688 !important +} + +.teal-border { + border-color: #009688 !important +} + +.teal-text { + color: #009688 !important +} + +.teal1 { + background-color: #e0f2f1 !important +} + +.teal2 { + background-color: #b2dfdb !important +} + +.teal3 { + background-color: #80cbc4 !important +} + +.teal4 { + background-color: #4db6ac !important +} + +.teal5 { + background-color: #26a69a !important +} + +.teal7 { + background-color: #00897b !important +} + +.teal8 { + background-color: #00796b !important +} + +.teal9 { + background-color: #00695c !important +} + +.teal10 { + background-color: #004d40 !important +} + +.green, +.green6 { + background-color: #4caf50 !important +} + +.green-border { + border-color: #4caf50 !important +} + +.green-text { + color: #4caf50 !important +} + +.green1 { + background-color: #e8f5e9 !important +} + +.green2 { + background-color: #c8e6c9 !important +} + +.green3 { + background-color: #a5d6a7 !important +} + +.green4 { + background-color: #81c784 !important +} + +.green5 { + background-color: #66bb6a !important +} + +.green7 { + background-color: #43a047 !important +} + +.green8 { + background-color: #388e3c !important +} + +.green9 { + background-color: #2e7d32 !important +} + +.green10 { + background-color: #1b5e20 !important +} + +.light-green, +.light-green6 { + background-color: #8bc34a !important +} + +.light-green-border { + border-color: #8bc34a !important +} + +.light-green-text { + color: #8bc34a !important +} + +.light-green1 { + background-color: #f1f8e9 !important +} + +.light-green2 { + background-color: #dcedc8 !important +} + +.light-green3 { + background-color: #c5e1a5 !important +} + +.light-green4 { + background-color: #aed581 !important +} + +.light-green5 { + background-color: #9ccc65 !important +} + +.light-green7 { + background-color: #7cb342 !important +} + +.light-green8 { + background-color: #689f38 !important +} + +.light-green9 { + background-color: #558b2f !important +} + +.light-green10 { + background-color: #33691e !important +} + +.lime, +.lime6 { + background-color: #cddc39 !important +} + +.lime-border { + border-color: #cddc39 !important +} + +.lime-text { + color: #cddc39 !important +} + +.lime1 { + background-color: #f9fbe7 !important +} + +.lime2 { + background-color: #f0f4c3 !important +} + +.lime3 { + background-color: #e6ee9c !important +} + +.lime4 { + background-color: #dce775 !important +} + +.lime5 { + background-color: #d4e157 !important +} + +.lime7 { + background-color: #c0ca33 !important +} + +.lime8 { + background-color: #afb42b !important +} + +.lime9 { + background-color: #9e9d24 !important +} + +.lime10 { + background-color: #827717 !important +} + +.yellow, +.yellow6 { + background-color: #ffeb3b !important +} + +.yellow-border { + border-color: #ffeb3b !important +} + +.yellow-text { + color: #ffeb3b !important +} + +.yellow1 { + background-color: #fffde7 !important +} + +.yellow2 { + background-color: #fff9c4 !important +} + +.yellow3 { + background-color: #fff59d !important +} + +.yellow4 { + background-color: #fff176 !important +} + +.yellow5 { + background-color: #ffee58 !important +} + +.yellow7 { + background-color: #fdd835 !important +} + +.yellow8 { + background-color: #fbc02d !important +} + +.yellow9 { + background-color: #f9a825 !important +} + +.yellow10 { + background-color: #f57f17 !important +} + +.amber, +.amber6 { + background-color: #ffc107 !important +} + +.amber-border { + border-color: #ffc107 !important +} + +.amber-text { + color: #ffc107 !important +} + +.amber1 { + background-color: #fff8e1 !important +} + +.amber2 { + background-color: #ffecb3 !important +} + +.amber3 { + background-color: #ffe082 !important +} + +.amber4 { + background-color: #ffd54f !important +} + +.amber5 { + background-color: #ffca28 !important +} + +.amber7 { + background-color: #ffb300 !important +} + +.amber8 { + background-color: #ffa000 !important +} + +.amber9 { + background-color: #ff8f00 !important +} + +.amber10 { + background-color: #ff6f00 !important +} + +.orange, +.orange6 { + background-color: #ff9800 !important +} + +.orange-border { + border-color: #ff9800 !important +} + +.orange-text { + color: #ff9800 !important +} + +.orange1 { + background-color: #fff3e0 !important +} + +.orange2 { + background-color: #ffe0b2 !important +} + +.orange3 { + background-color: #ffcc80 !important +} + +.orange4 { + background-color: #ffb74d !important +} + +.orange5 { + background-color: #ffa726 !important +} + +.orange7 { + background-color: #fb8c00 !important +} + +.orange8 { + background-color: #f57c00 !important +} + +.orange9 { + background-color: #ef6c00 !important +} + +.orange10 { + background-color: #e65100 !important +} + +.deep-orange, +.deep-orange6 { + background-color: #ff5722 !important +} + +.deep-orange-border { + border-color: #ff5722 !important +} + +.deep-orange-text { + color: #ff5722 !important +} + +.deep-orange1 { + background-color: #fbe9e7 !important +} + +.deep-orange2 { + background-color: #ffccbc !important +} + +.deep-orange3 { + background-color: #ffab91 !important +} + +.deep-orange4 { + background-color: #ff8a65 !important +} + +.deep-orange5 { + background-color: #ff7043 !important +} + +.deep-orange7 { + background-color: #f4511e !important +} + +.deep-orange8 { + background-color: #e64a19 !important +} + +.deep-orange9 { + background-color: #d84315 !important +} + +.deep-orange10 { + background-color: #bf360c !important +} + +.brown, +.brown6 { + background-color: #795548 !important +} + +.brown-border { + border-color: #795548 !important +} + +.brown-text { + color: #795548 !important +} + +.brown1 { + background-color: #efebe9 !important +} + +.brown2 { + background-color: #d7ccc8 !important +} + +.brown3 { + background-color: #bcaaa4 !important +} + +.brown4 { + background-color: #a1887f !important +} + +.brown5 { + background-color: #8d6e63 !important +} + +.brown7 { + background-color: #6d4c41 !important +} + +.brown8 { + background-color: #5d4037 !important +} + +.brown9 { + background-color: #4e342e !important +} + +.brown10 { + background-color: #3e2723 !important +} + +.blue-grey, +.blue-grey6 { + background-color: #607d8b !important +} + +.blue-grey-border { + border-color: #607d8b !important +} + +.blue-grey-text { + color: #607d8b !important +} + +.blue-grey1 { + background-color: #eceff1 !important +} + +.blue-grey2 { + background-color: #cfd8dc !important +} + +.blue-grey3 { + background-color: #b0bec5 !important +} + +.blue-grey4 { + background-color: #90a4ae !important +} + +.blue-grey5 { + background-color: #78909c !important +} + +.blue-grey7 { + background-color: #546e7a !important +} + +.blue-grey8 { + background-color: #455a64 !important +} + +.blue-grey9 { + background-color: #37474f !important +} + +.blue-grey10 { + background-color: #263238 !important +} + +.grey, +.grey6 { + background-color: #9e9e9e !important +} + +.grey-border { + border-color: #9e9e9e !important +} + +.grey-text { + color: #9e9e9e !important +} + +.grey1 { + background-color: #fafafa !important +} + +.grey2 { + background-color: #f5f5f5 !important +} + +.grey3 { + background-color: #eee !important +} + +.grey4 { + background-color: #e0e0e0 !important +} + +.grey5 { + background-color: #bdbdbd !important +} + +.grey7 { + background-color: #757575 !important +} + +.grey8 { + background-color: #616161 !important +} + +.grey9 { + background-color: #424242 !important +} + +.grey10 { + background-color: #212121 !important +} + +.horizontal { + display: inline-flex; + flex-direction: row !important; + gap: 1rem; + inline-size: auto !important; + max-inline-size: none !important +} + +.horizontal>* { + margin-block: 0 !important +} + +.vertical { + display: flex; + flex-direction: column !important +} + +:is(a, button, .button, .chip).vertical { + display: inline-flex; + gap: .25rem; + block-size: auto !important; + max-block-size: none !important; + padding-block: .5rem +} + +.vertical>* { + margin-inline: 0 !important +} + +.divider, +.small-divider, +.medium-divider, +.large-divider { + min-inline-size: 1.5rem; + min-block-size: auto; + block-size: .0625rem; + background-color: var(--outline-variant); + display: block; + margin: 0 !important +} + +.medium-divider { + margin: 1rem 0 !important +} + +.large-divider { + margin: 1.5rem 0 !important +} + +.small-divider { + margin: .5rem 0 !important +} + +.divider.vertical { + min-inline-size: auto; + min-block-size: 1.5rem; + inline-size: .0625rem +} + +.no-elevate { + box-shadow: none !important +} + +.small-elevate, +.elevate { + box-shadow: var(--elevate1) !important +} + +.medium-elevate { + box-shadow: var(--elevate2) !important +} + +.large-elevate { + box-shadow: var(--elevate3) !important +} + +.round { + border-radius: var(---round) +} + +.small-round, +.medium-round, +.large-round { + border-radius: var(---round) !important +} + +.top-round, +.bottom-round, +.left-round, +.right-round, +.medium-round, +.round { + ---round: 2rem +} + +.small-round { + ---round: .5rem +} + +.large-round { + ---round: 3.5rem +} + +.no-round, +.square, +.top-round, +.bottom-round, +.left-round, +.right-round { + border-radius: 0 !important +} + +.top-round { + border-start-start-radius: var(---round) !important; + border-start-end-radius: var(---round) !important +} + +.bottom-round { + border-end-end-radius: var(---round) !important; + border-end-start-radius: var(---round) !important +} + +.left-round { + border-start-start-radius: var(---round) !important; + border-end-start-radius: var(---round) !important +} + +.right-round { + border-start-end-radius: var(---round) !important; + border-end-end-radius: var(---round) !important +} + +.circle { + border-radius: 50% +} + +:is(button, .button, .chip).circle { + border-radius: 2.5rem +} + +:is(.circle, .square):not(i, img, video, svg), +:is(.circle, .square).chip.medium { + block-size: 2.5rem; + inline-size: 2.5rem; + padding: 0 +} + +:is(.circle, .square)>span { + display: none +} + +:is(.circle, .square).small:not(i, img, video, svg), +:is(.circle, .square).chip { + block-size: 2rem; + inline-size: 2rem +} + +:is(.circle, .square).large:not(i, img, video, svg) { + block-size: 3rem; + inline-size: 3rem +} + +:is(.circle, .square).extra:not(i, img, video, svg) { + block-size: 3.5rem; + inline-size: 3.5rem +} + +:is(.circle, .square).round { + border-radius: 1rem !important +} + +.border:not(table, .field) { + box-sizing: border-box; + border: .0625rem solid var(--outline); + background-color: transparent; + box-shadow: none +} + +.no-border { + border-color: transparent !important +} + +:is(nav, .row, dialog.max, header.fixed, footer.fixed, menu > a, menu.max, table, .tabs):not(.round) { + border-radius: 0 +} + +:is(.no-margin, .auto-margin, .tiny-margin, .small-margin, .medium-margin, .margin, .large-margin):not(.left-margin, .right-margin, .top-margin, .bottom-margin, .horizontal-margin, .vertical-margin) { + margin: var(---margin) !important +} + +.no-margin, +.auto-margin, +.tiny-margin, +.small-margin, +.medium-margin, +.margin, +.large-margin, +.left-margin, +.right-margin, +.top-margin, +.bottom-margin, +.horizontal-margin, +.vertical-margin { + ---margin: 1rem +} + +.no-margin { + ---margin: 0 +} + +.auto-margin { + ---margin: auto +} + +.tiny-margin { + ---margin: .25rem +} + +.small-margin { + ---margin: .5rem +} + +.large-margin { + ---margin: 1.5rem +} + +.left-margin, +.horizontal-margin { + margin-inline-start: var(---margin) !important +} + +.right-margin, +.horizontal-margin { + margin-inline-end: var(---margin) !important +} + +.top-margin, +.vertical-margin { + margin-block-start: var(---margin) !important +} + +.bottom-margin, +.vertical-margin { + margin-block-end: var(---margin) !important +} + +.no-opacity { + opacity: 1 !important +} + +.opacity { + opacity: 0 !important +} + +.small-opacity { + opacity: .75 !important +} + +.medium-opacity { + opacity: .5 !important +} + +.large-opacity { + opacity: .25 !important +} + +:is(.no-padding, .auto-padding, .tiny-padding, .small-padding, .medium-padding, .padding, .large-padding):not(.left-padding, .right-padding, .top-padding, .bottom-padding, .horizontal-padding, .vertical-padding) { + padding: var(---padding) !important +} + +.no-padding, +.auto-padding, +.tiny-padding, +.small-padding, +.medium-padding, +.padding, +.large-padding, +.left-padding, +.right-padding, +.top-padding, +.bottom-padding, +.horizontal-padding, +.vertical-padding { + ---padding: 1rem +} + +.no-padding { + ---padding: 0 +} + +.auto-padding { + ---padding: auto +} + +.tiny-padding { + ---padding: .25rem +} + +.small-padding { + ---padding: .5rem +} + +.large-padding { + ---padding: 1.5rem +} + +.left-padding, +.horizontal-padding { + padding-inline-start: var(---padding) !important +} + +.right-padding, +.horizontal-padding { + padding-inline-end: var(---padding) !important +} + +.top-padding, +.vertical-padding { + padding-block-start: var(---padding) !important +} + +.bottom-padding, +.vertical-padding { + padding-block-end: var(---padding) !important +} + +.front { + z-index: 10 !important +} + +.back { + z-index: -10 !important +} + +.left { + inset-inline-start: 0 +} + +.right { + inset-inline-end: 0 +} + +.top { + inset-block-start: 0 +} + +.bottom { + inset-block-end: 0 +} + +.center { + inset-inline-start: 50%; + transform: translate(-50%) +} + +[dir=rtl] .center { + transform: translate(50%) +} + +.middle { + inset-block-start: 50%; + transform: translateY(-50%) +} + +.middle.center { + transform: translate(-50%, -50%) +} + +[dir=rtl] .middle.center { + transform: translate(50%, -50%) +} + +.scroll { + overflow: auto +} + +.no-scroll { + overflow: hidden +} + +.small-width { + inline-size: 12rem !important; + max-inline-size: 100% +} + +.medium-width { + inline-size: 24rem !important; + max-inline-size: 100% +} + +.large-width { + inline-size: 36rem !important; + max-inline-size: 100% +} + +.small-height { + block-size: 12rem !important +} + +.medium-height { + block-size: 24rem !important +} + +.large-height { + block-size: 36rem !important +} + +.wrap { + display: block; + white-space: normal +} + +.no-wrap:not(menu) { + display: flex; + white-space: nowrap +} + +.tiny-space:not(nav, .row, .grid, table, .tooltip) { + block-size: .5rem +} + +:is(.space, .small-space):not(nav, .row, .grid, table, .tooltip) { + block-size: 1rem +} + +.medium-space:not(nav, .row, .grid, table, .tooltip) { + block-size: 2rem +} + +.large-space:not(nav, .row, .grid, table, .tooltip) { + block-size: 3rem +} + +.responsive { + inline-size: -webkit-fill-available; + inline-size: -moz-available +} + +@media only screen and (max-width: 600px) { + + .m:not(.s), + .l:not(.s), + .m.l:not(.s) { + display: none + } +} + +@media only screen and (min-width: 601px) and (max-width: 992px) { + + .s:not(.m), + .l:not(.m), + .s.l:not(.m) { + display: none + } +} + +@media only screen and (min-width: 993px) { + + .m:not(.l), + .s:not(.l), + .m.s:not(.l) { + display: none + } +} + +html { + font-size: var(--size) +} + +body { + font-family: var(--font); + font-size: .875rem; + line-height: 1.25 +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 400; + display: flex; + align-items: center; + margin-block-end: .5rem; + line-height: normal +} + +*+h1, +*+h2, +*+h3, +*+h4, +*+h5, +*+h6 { + margin-block-start: 1rem +} + +h1 { + font-size: 3.5625rem +} + +h2 { + font-size: 2.8125rem +} + +h3 { + font-size: 2.25rem +} + +h4 { + font-size: 2rem +} + +h5 { + font-size: 1.75rem +} + +h6 { + font-size: 1.5rem +} + +h1.small { + font-size: 3.0625rem +} + +h2.small { + font-size: 2.3125rem +} + +h3.small { + font-size: 1.75rem +} + +h4.small { + font-size: 1.5rem +} + +h5.small { + font-size: 1.25rem +} + +h6.small { + font-size: 1rem +} + +h1.large { + font-size: 4.0625rem +} + +h2.large { + font-size: 3.3125rem +} + +h3.large { + font-size: 2.75rem +} + +h4.large { + font-size: 2.5rem +} + +h5.large { + font-size: 2.25rem +} + +h6.large { + font-size: 2rem +} + +.link { + color: var(--primary) !important +} + +.inverse-link { + color: var(--inverse-primary) !important +} + +.truncate { + overflow: hidden; + white-space: nowrap !important; + text-overflow: ellipsis; + flex: inherit +} + +.truncate>* { + white-space: nowrap !important +} + +.small-text { + font-size: .75rem +} + +.medium-text { + font-size: .875rem +} + +.large-text { + font-size: 1rem +} + +.upper { + text-transform: uppercase +} + +.lower { + text-transform: lowercase +} + +.capitalize { + text-transform: capitalize +} + +.bold { + font-weight: 700 +} + +.overline { + text-decoration: line-through +} + +.underline { + text-decoration: underline +} + +.italic { + font-style: italic +} + +p { + margin: .5rem 0 +} + +.no-line { + line-height: normal +} + +.tiny-line { + line-height: 1.25 +} + +.small-line { + line-height: 1.5 +} + +.medium-line { + line-height: 1.75 +} + +.large-line { + line-height: 2 +} + +.extra-line { + line-height: 2.25 +} + +.wave:after, +.chip:after, +.wave.light:after, +:is(.button, button):after { + content: ""; + position: absolute; + inset: 0 auto auto 0; + z-index: 1; + border-radius: inherit; + inline-size: 100%; + block-size: 100%; + background-position: center; + background-image: radial-gradient(circle, rgb(255 255 255 / .4) 1%, transparent 1%); + opacity: 0; + transition: none +} + +.wave.dark:after, +.wave.row:after, +.chip:after, +:is(.button, button).border:after, +:is(.button, button).transparent:after { + background-image: radial-gradient(circle, rgb(150 150 150 / .2) 1%, transparent 1%) +} + +.wave.none:after { + inset: 0 auto auto -.25rem; + padding: 0 .25rem +} + +.wave.none:not(.small, .medium, .large, .extra):after { + inset: -.25rem auto auto -.25rem; + padding: .25rem +} + +:is(.wave, .chip, .button, button):is(:focus, :hover):after { + background-size: 15000%; + opacity: 1; + transition: var(--speed2) background-size linear +} + +:is(.wave, .chip, .button, button):active:after { + background-size: 5000%; + opacity: 0; + transition: none +} + +.no-wave:after, +.no-wave:is(:hover, :active):after { + display: none +} + +.badge { + display: inline-flex; + align-items: center; + justify-content: center; + position: absolute; + font-size: .75rem; + text-transform: none; + z-index: 1; + padding: 0 .375rem; + background-color: var(--error); + color: var(--on-error); + inset: 0 0 auto auto; + block-size: 1.25rem; + line-height: normal; + transform: translate(50%, -100%) +} + +[dir=rtl] .badge { + transform: translate(-50%, -100%) +} + +.badge.none { + inset: auto; + transform: none; + position: relative; + margin: 0 .125rem +} + +.badge.top { + inset: 0 auto auto 50%; + transform: translate(-50%, -100%) +} + +[dir=rtl] .badge.top { + transform: translate(50%, -100%) +} + +.badge.bottom { + inset: auto auto 0 50%; + transform: translate(-50%, 100%) +} + +[dir=rtl] .badge.bottom { + transform: translate(50%, 100%) +} + +.badge.left { + inset: 50% auto auto 0; + transform: translate(-100%, -50%) +} + +[dir=rtl] .badge.left { + transform: translate(100%, -50%) +} + +.badge.right { + inset: 50% 0 auto auto; + transform: translate(100%, -50%) +} + +[dir=rtl] .badge.right { + transform: translate(-100%, -50%) +} + +.badge.top.left { + inset: 0 auto auto 0; + transform: translate(-50%, -100%) +} + +[dir=rtl] .badge.top.left { + transform: translate(50%, -100%) +} + +.badge.bottom.left { + inset: auto auto 0 0; + transform: translate(-50%, 100%) +} + +[dir=rtl] .badge.bottom.left { + transform: translate(50%, 100%) +} + +.badge.top.right { + inset: 0 0 auto auto; + transform: translate(50%, -100%) +} + +[dir=rtl] .badge.top.right { + transform: translate(-50%, -100%) +} + +.badge.bottom.right { + inset: auto 0 0 auto; + transform: translate(50%, 100%) +} + +[dir=rtl] .badge.bottom.right { + transform: translate(-50%, 100%) +} + +.badge.border { + border-color: var(--error); + color: var(--error) +} + +.badge:is(.circle, .square) { + padding: 0; + text-align: center; + inline-size: 1.25rem; + block-size: 1.25rem +} + +.button, +button { + box-sizing: content-box; + display: inline-flex; + align-items: center; + justify-content: center; + block-size: 2.5rem; + min-inline-size: 2.5rem; + font-size: .875rem; + font-weight: 500; + color: var(--on-primary); + padding: 0 1.5rem; + background-color: var(--primary); + margin: 0 .5rem; + border-radius: 1.25rem; + transition: var(--speed3) transform, var(--speed3) border-radius, var(--speed3) padding; + user-select: none; + gap: 1rem; + line-height: normal +} + +:is(button, .button).small { + block-size: 2rem; + min-inline-size: 2rem; + font-size: .875rem; + border-radius: 1rem +} + +:is(button, .button).large { + block-size: 3rem; + min-inline-size: 3rem; + border-radius: 1.5rem +} + +:is(.button, button):is(.extra, .extend) { + block-size: 3.5rem; + min-inline-size: 3.5rem; + font-size: 1rem; + border-radius: 1.75rem +} + +:is(button, .button).border { + border-color: var(--outline); + color: var(--primary) +} + +.extend>span { + display: none +} + +.extend:is(:hover, .active) { + inline-size: auto; + padding: 0 1.5rem +} + +.extend:is(:hover, .active)>i+span { + display: inherit; + margin-inline-start: 1.5rem +} + +.extend:is(:hover, .active)>:is(img, svg)+span { + display: inherit; + margin-inline-start: 2.5rem +} + +:is(.button, button):is([disabled]) { + opacity: .5; + cursor: not-allowed +} + +:is(.button):is([disabled]) { + pointer-events: none +} + +:is(.button, button):is([disabled]):before, +:is(.button, button):is([disabled]):after { + display: none +} + +:is(.button, button).fill { + background-color: var(--secondary-container) !important; + color: var(--on-secondary-container) !important +} + +:is(.button, button).vertical { + border-radius: 2rem +} + +article { + box-shadow: var(--elevate1); + background-color: var(--surface-container-low); + color: var(--on-surface); + padding: 1rem; + border-radius: .75rem; + display: block; + transition: var(--speed3) transform, var(--speed3) border-radius, var(--speed3) padding +} + +*+article { + margin-block-start: 1rem +} + +article.small { + block-size: 12rem +} + +article.medium { + block-size: 20rem +} + +article.large { + block-size: 32rem +} + +.chip { + box-sizing: content-box; + display: inline-flex; + align-items: center; + justify-content: center; + block-size: 2rem; + min-inline-size: 2rem; + font-size: .875rem; + font-weight: 500; + background-color: transparent; + border: .0625rem solid var(--outline); + color: var(--on-surface-variant); + padding: 0 1rem; + margin: 0 .5rem; + text-transform: none; + border-radius: .5rem; + transition: var(--speed3) transform, var(--speed3) border-radius, var(--speed3) padding; + user-select: none; + gap: 1rem; + line-height: normal +} + +.chip.medium { + block-size: 2.5rem; + min-inline-size: 2.5rem +} + +.chip.large { + block-size: 3rem; + min-inline-size: 3rem +} + +.chip.fill { + background-color: var(--secondary-container) !important; + border-color: transparent +} + +.chip.border { + border-color: var(--outline) +} + +.chip.round.small { + border-radius: 1rem +} + +.chip.round { + border-radius: 1.25rem +} + +.chip.round.large { + border-radius: 1.5rem +} + +:is(main, header, footer).responsive { + ---padding: 6rem; + max-inline-size: calc(75rem + var(---padding)); + margin: 0 auto +} + +main.responsive { + padding: .5rem; + overflow-x: hidden; + min-block-size: 100dvh; +} + +:is(main, header, footer).responsive.max { + max-inline-size: 100% +} + +nav.bottom:not(.s, .m, .l)~.responsive:not(header) { + padding-block-end: 6rem +} + +nav.top:not(.s, .m, .l)~.responsive:not(footer) { + padding-block-start: 6rem +} + +nav.left:not(.s, .m, .l)~.responsive { + padding-inline-start: var(---padding) +} + +nav.right:not(.s, .m, .l)~.responsive { + padding-inline-end: var(---padding) +} + +nav.drawer:not(.s, .m, .l)~.responsive { + ---padding: 20rem +} + +@media only screen and (max-width: 600px) { + nav.s.bottom~.responsive:not(header) { + padding-block-end: 6rem + } + + nav.s.top~.responsive:not(footer) { + padding-block-start: 6rem + } + + nav.drawer.s~.responsive { + ---padding: 20rem + } + + nav.s.left~.responsive { + padding-inline-start: var(---padding) + } + + nav.s.right~.responsive { + padding-inline-end: var(---padding) + } +} + +@media only screen and (min-width: 601px) and (max-width: 992px) { + nav.m.bottom~.responsive:not(header) { + padding-block-end: 6rem + } + + nav.m.top~.responsive:not(footer) { + padding-block-start: 6rem + } + + nav.drawer.m~.responsive { + ---padding: 20rem + } + + nav.m.left~.responsive { + padding-inline-start: var(---padding) + } + + nav.m.right~.responsive { + padding-inline-end: var(---padding) + } +} + +@media only screen and (min-width: 993px) { + nav.l.bottom~.responsive:not(header) { + padding-block-end: 6rem + } + + nav.l.top~.responsive:not(footer) { + padding-block-start: 6rem + } + + nav.drawer.l~.responsive { + ---padding: 20rem + } + + nav.l.left~.responsive { + padding-inline-start: var(---padding) + } + + nav.l.right~.responsive { + padding-inline-end: var(---padding) + } +} + +@media only screen and (max-width: 600px) { + main.responsive { + padding-inline-end: .5rem; + padding-inline-start: .5rem + } +} + +dialog { + display: block; + border: none; + opacity: 0; + visibility: hidden; + position: fixed; + box-shadow: var(--elevate2); + color: var(--on-surface); + background-color: var(--surface-container-high); + padding: 1.5rem; + z-index: 100; + inset: 10% auto auto 50%; + min-inline-size: 20rem; + max-inline-size: 100%; + max-block-size: 80%; + overflow-x: hidden; + overflow-y: auto; + transition: var(--speed3) all, 0s background-color; + border-radius: 1.75rem; + transform: translate(-50%, -4rem) +} + +[dir=rtl] dialog { + transform: translate(50%, -4rem) +} + +dialog::backdrop { + display: none +} + +dialog.small { + inline-size: 25%; + block-size: 25% +} + +dialog.medium { + inline-size: 50%; + block-size: 50% +} + +dialog.large { + inline-size: 75%; + block-size: 75% +} + +dialog:is(.active, [open]) { + opacity: 1; + visibility: visible; + transform: translate(-50%) +} + +[dir=rtl] dialog:is(.active, [open]) { + transform: translate(50%) +} + +dialog:is(.active, [open]):is(.left, .right, .top, .bottom, .max), +[dir=rtl] dialog:is(.active, [open]):is(.left, .right, .top, .bottom, .max) { + transform: translate(0) +} + +dialog.top { + opacity: 1; + padding: 1rem; + inset: 0 auto auto 0; + block-size: auto; + inline-size: 100%; + min-inline-size: auto; + max-block-size: 100%; + transform: translateY(-100%); + border-radius: 0 0 1rem 1rem +} + +dialog.left { + opacity: 1; + padding: 1rem; + inset: 0 auto auto 0; + inline-size: auto; + block-size: 100%; + max-block-size: 100%; + border-radius: 0 1rem 1rem 0; + background-color: var(--surface); + transform: translate(-100%) +} + +[dir=rtl] dialog.left { + transform: translate(100%) +} + +dialog.right { + opacity: 1; + padding: 1rem; + inset: 0 0 auto auto; + inline-size: auto; + block-size: 100%; + max-block-size: 100%; + border-radius: 1rem 0 0 1rem; + background-color: var(--surface); + transform: translate(100%) +} + +[dir=rtl] dialog.right { + transform: translate(-100%) +} + +dialog.bottom { + opacity: 1; + padding: 1rem; + inset: auto auto 0 0; + block-size: auto; + inline-size: 100%; + min-inline-size: auto; + max-block-size: 100%; + transform: translateY(100%); + border-radius: 1rem 1rem 0 0 +} + +dialog.max { + inset: 0 auto auto 0; + inline-size: 100%; + block-size: 100%; + max-inline-size: 100%; + max-block-size: 100%; + transform: translateY(4rem); + background-color: var(--surface) +} + +dialog.small:is(.left, .right) { + inline-size: 20rem +} + +dialog.medium:is(.left, .right) { + inline-size: 32rem +} + +dialog.large:is(.left, .right) { + inline-size: 44rem +} + +dialog.small:is(.top, .bottom) { + block-size: 16rem +} + +dialog.medium:is(.top, .bottom) { + block-size: 24rem +} + +dialog.large:is(.top, .bottom) { + block-size: 32rem +} + +dialog>a.row:is(:hover, .active) { + background-color: var(--secondary-container) +} + +dialog>.row { + padding: .75rem +} + +summary.none { + list-style-type: none +} + +summary.none::-webkit-details-marker { + display: none +} + +summary { + cursor: pointer +} + +summary:focus { + outline: none +} + +.field { + block-size: 3rem; + margin-block-end: 2rem +} + +*+.field { + margin-block-start: 1rem +} + +.grid>*>.field { + margin-block-end: 1rem +} + +.grid>*>.field+.field { + margin-block-start: 2rem +} + +.grid.no-space>*>.field+.field { + margin-block-start: 1rem +} + +.grid.medium-space>*>.field+.field { + margin-block-start: 2.5rem +} + +.grid.large-space>*>.field+.field { + margin-block-start: 3rem +} + +.field.small { + block-size: 2.5rem +} + +.field.large { + block-size: 3.5rem +} + +.field.extra { + block-size: 4rem +} + +.field { + border-radius: .25rem .25rem 0 0 +} + +.field.border { + border-radius: .25rem +} + +.field.round.small { + border-radius: 1.25rem +} + +.field.round { + border-radius: 1.5rem +} + +.field.round.large { + border-radius: 1.75rem +} + +.field.round.extra { + border-radius: 2rem +} + +.field:before { + content: ""; + position: absolute; + inset: 0; + border-radius: inherit; + background-color: inherit +} + +.field.fill:before { + background-color: var(--surface-container-highest); + color: var(--on-surface-variant) +} + +.field>:is(i, img, svg, progress, a:not(.helper, .error)) { + position: absolute; + inset: 50% auto auto auto; + transform: translateY(-50%); + cursor: pointer; + z-index: 0; + inline-size: 1.5rem; + block-size: 1.5rem +} + +.field>:is(i, img, svg, progress, a:not(.helper, .error)), +[dir=rtl] .field>:is(i, a:not(.helper, .error)):first-child { + inset: 50% 1rem auto auto +} + +.field>:is(i, img, svg, progress, a:not(.helper, .error)):first-child, +[dir=rtl] .field>:is(i, a:not(.helper, .error)) { + inset: 50% auto auto 1rem +} + +.field.invalid>i { + color: var(--error) +} + +.field>progress.circle { + inset-block-start: calc(50% - .75rem); + border-width: .1875rem +} + +.field>a:not(.helper, .error) { + z-index: 10 +} + +.field>a>:is(i, img, svg, progress, a:not(.helper, .error)) { + inline-size: 1.5rem; + block-size: 1.5rem +} + +.field>:is(input, textarea, select) { + appearance: none; + border: .0625rem solid transparent; + padding: 0 .9375rem; + font-family: inherit; + font-size: 1rem; + inline-size: 100%; + block-size: 100%; + outline: none; + z-index: 1; + background: none; + resize: none +} + +.field>:is(input, textarea, select):focus { + border: .125rem solid transparent; + padding: 0 .875rem +} + +input[type=file], +input[type=color], +:not(.field)>input[type^=date], +:not(.field)>input[type^=time], +input::-webkit-inner-spin-button, +input::-webkit-outer-spin-button, +input::-webkit-calendar-picker-indicator { + opacity: 0; + position: absolute; + inset: 0; + inline-size: 100%; + block-size: 100%; + margin: 0; + padding: 0; + border: 0; + outline: 0; + z-index: 2 !important +} + +input::-webkit-search-decoration, +input::-webkit-search-cancel-button, +input::-webkit-search-results-button, +input::-webkit-search-results-decoration { + display: none +} + +.field.border>:is(input, textarea, select) { + border-color: var(--outline) +} + +.field.border>:is(input, textarea, select):focus { + border-color: var(--primary) +} + +.field.round>:is(input, textarea, select) { + padding-inline: 1.4376rem +} + +.field.round>:is(input, textarea, select):focus { + padding-inline: 1.375rem +} + +.field.prefix>:is(input, textarea, select) { + padding-inline-start: 2.9375rem +} + +.field.prefix>.slider { + margin-inline-start: 3.5rem +} + +.field.prefix>:is(input, textarea, select):focus { + padding-inline-start: 2.875rem +} + +.field.suffix>:is(input, textarea, select) { + padding-inline-end: 2.9375rem +} + +.field.suffix>.slider { + margin-inline-end: 3.5rem +} + +.field.suffix>:is(input, textarea, select):focus { + padding-inline-end: 2.875rem +} + +.field:not(.border, .round)>:is(input, textarea, select) { + border-block-end-color: var(--outline) +} + +.field:not(.border, .round)>:is(input, textarea, select):focus { + border-block-end-color: var(--primary) +} + +.field.round:not(.border, .fill)>:is(input, textarea, select), +.field.round:not(.border)>:is(input, textarea, select):focus { + box-shadow: var(--elevate1) +} + +.field.round:not(.border, .fill)>:is(input, textarea, select):focus { + box-shadow: var(--elevate2) +} + +.field.invalid:not(.border, .round)>:is(input, textarea, select), +.field.invalid:not(.border, .round)>:is(input, textarea, select):focus { + border-block-end-color: var(--error) +} + +.field.invalid.border>:is(input, textarea, select), +.field.invalid.border>:is(input, textarea, select):focus { + border-color: var(--error) +} + +.field:has(> :disabled) { + opacity: .5; + cursor: not-allowed +} + +.field>:disabled { + cursor: not-allowed +} + +.field.small.textarea { + block-size: 4.5rem +} + +.field.textarea { + block-size: 5.5rem +} + +.field.large.textarea { + block-size: 6.5rem +} + +.field.extra.textarea { + block-size: 7.5rem +} + +.field>select>option { + background-color: var(--surface-container); + color: var(--on-surface) +} + +.field.label>:is(input, select) { + padding-block-start: 1rem +} + +.field.label.border:not(.fill)>:is(input, select) { + padding-block-start: 0 +} + +.field.label.small>textarea { + padding-block-start: 1.125rem +} + +.field.label>textarea { + padding-block-start: 1.375rem +} + +.field.label.large>textarea { + padding-block-start: 1.625rem +} + +.field.label.extra>textarea { + padding-block-start: 1.875rem +} + +.field.small>textarea, +.field.small:not(.label)>textarea:focus, +.field.small.border:not(.fill)>textarea { + padding-block-start: .625rem +} + +.field>textarea, +.field:not(.label)>textarea:focus, +.field.border:not(.fill)>textarea { + padding-block-start: .875rem +} + +.field.large>textarea, +.field.large:not(.label)>textarea:focus, +.field.large.border:not(.fill)>textarea { + padding-block-start: 1.125rem +} + +.field.extra>textarea, +.field.extra:not(.label)>textarea:focus, +.field.extra.border:not(.fill)>textarea { + padding-block-start: 1.375rem +} + +.field.small.border:not(.fill)>textarea:focus { + padding-block-start: .5625rem !important +} + +.field.border:not(.fill)>textarea:focus { + padding-block-start: .8125rem !important +} + +.field.large.border:not(.fill)>textarea:focus { + padding-block-start: 1.0625rem !important +} + +.field.extra.border:not(.fill)>textarea:focus { + padding-block-start: 1.3125rem !important +} + +.field.label>label { + position: absolute; + inset: -.5rem auto auto 1rem; + display: flex; + inline-size: calc(100% - 5rem); + block-size: 4rem; + line-height: 4rem; + font-size: 1rem; + transition: all .2s; + gap: .25rem; + white-space: nowrap +} + +.field.label.small>label { + block-size: 3.5rem; + line-height: 3.5rem +} + +.field.label.large>label { + block-size: 4.5rem; + line-height: 4.5rem +} + +.field.label.extra>label { + block-size: 5rem; + line-height: 5rem +} + +.field.label.border.prefix:not(.fill)>:is(label.active, :focus + label, [placeholder]:not(:placeholder-shown) + label, select + label) { + inset-inline-start: 1rem +} + +.field.label.round>label, +.field.label.border.prefix.round:not(.fill)>:is(label.active, :focus + label, [placeholder]:not(:placeholder-shown) + label, select + label) { + inset-inline-start: 1.5rem +} + +.field.label.prefix>label { + inset-inline-start: 3rem +} + +.field.label>:is(label.active, :focus + label, [placeholder]:not(:placeholder-shown) + label, select + label) { + block-size: 2.5rem; + line-height: 2.5rem; + font-size: .75rem +} + +.field.label.border:not(.fill)>:is(label.active, :focus + label, [placeholder]:not(:placeholder-shown) + label, select + label) { + block-size: 1rem; + line-height: 1rem +} + +.field.label.border:not(.fill)>label:after { + content: ""; + display: block; + margin-block-start: .5rem; + border-block-start: .0625rem solid var(--outline); + block-size: 1rem; + transition: none; + flex: auto +} + +.field.label.border:not(.fill)>:focus+label:after { + border-block-start: .125rem solid var(--primary) +} + +.field.label.border:not(.fill)>:is(input, textarea):is(:focus, [placeholder]:not(:placeholder-shown), .active), +.field.label.border:not(.fill)>select { + clip-path: polygon(-2% -2%, .75rem -2%, .75rem .5rem, calc(100% - 5rem) .5rem, calc(100% - 5rem) -2%, 102% -2%, 102% 102%, -2% 102%) +} + +[dir=rtl] .field.label.border:not(.fill)>:is(input, textarea):is(:focus, [placeholder]:not(:placeholder-shown), .active), +[dir=rtl] .field.label.border:not(.fill)>select { + clip-path: polygon(-2% -2%, 5rem -2%, 5rem .5rem, calc(100% - .75rem) .5rem, calc(100% - .75rem) -2%, 102% -2%, 102% 102%, -2% 102%) +} + +.field.label.border.round:not(.fill)>:is(input, textarea):is(:focus, [placeholder]:not(:placeholder-shown), .active), +.field.label.border.round:not(.fill)>select { + clip-path: polygon(-2% -2%, 1.25rem -2%, 1.25rem .5rem, calc(100% - 5rem) .5rem, calc(100% - 5rem) -2%, 102% -2%, 102% 102%, -2% 102%) +} + +[dir=rtl] .field.label.border.round:not(.fill)>:is(input, textarea):is(:focus, [placeholder]:not(:placeholder-shown), .active), +[dir=rtl] .field.label.border.round:not(.fill)>select { + clip-path: polygon(-2% -2%, 5rem -2%, 5rem .5rem, calc(100% - 1.25rem) .5rem, calc(100% - 1.25rem) -2%, 102% -2%, 102% 102%, -2% 102%) +} + +.field.label>:focus+label { + color: var(--primary) +} + +.field.label.invalid>label, +.field.label.invalid>label:after { + color: var(--error) !important; + border-color: var(--error) !important +} + +.field.label>label>a { + block-size: inherit; + line-height: inherit; + inline-size: 1rem +} + +.field.label>label>a>:is(i, img, svg) { + block-size: 1rem; + line-height: 1rem; + inline-size: 1rem; + font-size: 1rem +} + +.field>:is(.helper, .error) { + position: absolute; + inset: auto auto 0 1rem; + transform: translateY(100%); + font-size: .75rem; + background: none !important; + padding-block-start: .125rem +} + +a.helper { + color: var(--primary) +} + +.field>.error { + color: var(--error) !important +} + +.field.round>:is(.helper, .error) { + inset-inline-start: 1.5rem +} + +.field.invalid>.helper { + display: none +} + +table td>.field { + margin: 0 +} + +.grid { + ---gap: 1rem; + display: grid; + grid-template-columns: repeat(12, calc(8.33% - var(---gap) + (var(---gap) / 12))); + gap: var(---gap) +} + +*+.grid { + margin-block-start: 1rem +} + +.grid.no-space { + ---gap: 0rem +} + +.grid.medium-space { + ---gap: 1.5rem +} + +.grid.large-space { + ---gap: 2rem +} + +.s1 { + grid-area: auto/span 1 +} + +.s2 { + grid-area: auto/span 2 +} + +.s3 { + grid-area: auto/span 3 +} + +.s4 { + grid-area: auto/span 4 +} + +.s5 { + grid-area: auto/span 5 +} + +.s6 { + grid-area: auto/span 6 +} + +.s7 { + grid-area: auto/span 7 +} + +.s8 { + grid-area: auto/span 8 +} + +.s9 { + grid-area: auto/span 9 +} + +.s10 { + grid-area: auto/span 10 +} + +.s11 { + grid-area: auto/span 11 +} + +.s12 { + grid-area: auto/span 12 +} + +@media only screen and (min-width: 601px) { + .m1 { + grid-area: auto/span 1 + } + + .m2 { + grid-area: auto/span 2 + } + + .m3 { + grid-area: auto/span 3 + } + + .m4 { + grid-area: auto/span 4 + } + + .m5 { + grid-area: auto/span 5 + } + + .m6 { + grid-area: auto/span 6 + } + + .m7 { + grid-area: auto/span 7 + } + + .m8 { + grid-area: auto/span 8 + } + + .m9 { + grid-area: auto/span 9 + } + + .m10 { + grid-area: auto/span 10 + } + + .m11 { + grid-area: auto/span 11 + } + + .m12 { + grid-area: auto/span 12 + } +} + +@media only screen and (min-width: 993px) { + .l1 { + grid-area: auto/span 1 + } + + .l2 { + grid-area: auto/span 2 + } + + .l3 { + grid-area: auto/span 3 + } + + .l4 { + grid-area: auto/span 4 + } + + .l5 { + grid-area: auto/span 5 + } + + .l6 { + grid-area: auto/span 6 + } + + .l7 { + grid-area: auto/span 7 + } + + .l8 { + grid-area: auto/span 8 + } + + .l9 { + grid-area: auto/span 9 + } + + .l10 { + grid-area: auto/span 10 + } + + .l11 { + grid-area: auto/span 11 + } + + .l12 { + grid-area: auto/span 12 + } +} + +i { + ---size: 1.5rem; + font-family: var(--font-icon); + font-weight: 400; + font-style: normal; + font-size: var(---size); + letter-spacing: normal; + text-transform: none; + display: inline-flex; + align-items: center; + justify-content: center; + white-space: nowrap; + word-wrap: normal; + direction: ltr; + font-feature-settings: "liga"; + -webkit-font-smoothing: antialiased; + vertical-align: middle; + text-align: center; + overflow: hidden; + inline-size: var(---size); + min-inline-size: var(---size); + block-size: var(---size); + min-block-size: var(---size); + box-sizing: content-box; + line-height: normal +} + +i.tiny { + ---size: 1rem +} + +.chip>i, +i.small { + ---size: 1.25rem +} + +i.medium { + ---size: 1.5rem +} + +i.large { + ---size: 1.75rem +} + +i.extra { + ---size: 2rem +} + +i.fill, +a.row:is(:hover, :focus)>i, +.transparent:is(:hover, :focus)>i { + font-variation-settings: "FILL" 1 +} + +i>:is(img, svg) { + inline-size: 100%; + block-size: 100%; + background-size: 100%; + border-radius: inherit; + position: absolute; + inset: 0 auto auto 0; + padding: inherit +} + +i[class*=fa-] { + font-size: calc(var(---size) * .85); + line-height: normal; + block-size: auto; + min-block-size: auto +} + +.absolute { + position: absolute +} + +.fixed { + position: fixed +} + +:is(.absolute, .fixed).left.right { + inline-size: auto +} + +:is(.absolute, .fixed).left.right.small { + block-size: 20rem +} + +:is(.absolute, .fixed).left.right.medium { + block-size: 28rem +} + +:is(.absolute, .fixed).left.right.large { + block-size: 44rem +} + +:is(.absolute, .fixed).top.bottom.small { + inline-size: 20rem +} + +:is(.absolute, .fixed).top.bottom.medium { + inline-size: 28rem +} + +:is(.absolute, .fixed).top.bottom.large { + inline-size: 44rem +} + +header, +footer { + padding: 0 1rem; + background-color: var(--surface-container) +} + +:is(header, footer, menu > *).fixed { + position: sticky; + inset: 0; + z-index: 12; + background-color: inherit +} + +:is(dialog, menu)>:is(header, footer) { + padding: 0; + background-color: inherit +} + +article>:is(header, footer) { + padding: inherit; + padding-inline: 0; + z-index: 11 !important +} + +:is(dialog, article, .padding, .medium-padding)>header.fixed { + transform: translateY(-1rem) +} + +:is(dialog, article, .padding, .medium-padding)>footer.fixed { + transform: translateY(1rem) +} + +.no-padding>:is(header, footer).fixed { + transform: none +} + +.small-padding>header.fixed { + transform: translateY(-.5rem) +} + +.small-padding>footer.fixed { + transform: translateY(.5rem) +} + +.large-padding>header.fixed { + transform: translateY(-1.5rem) +} + +.large-padding>footer.fixed { + transform: translateY(1.5rem) +} + +svg { + fill: currentColor +} + +:is(img, svg, video):is(.small, .medium, .large, .tiny, .extra, .round, .circle, .responsive) { + object-fit: cover; + object-position: center; + transition: var(--speed3) transform, var(--speed3) border-radius, var(--speed3) padding; + block-size: 3rem; + inline-size: 3rem +} + +:is(img, svg, video).round { + border-radius: .5rem +} + +:is(img, svg, video).tiny { + block-size: 2rem; + inline-size: 2rem +} + +:is(img, svg, video).small { + block-size: 2.5rem; + inline-size: 2.5rem +} + +:is(img, svg, video).large { + block-size: 3.5rem; + inline-size: 3.5rem +} + +:is(img, svg, video).extra { + block-size: 4rem; + inline-size: 4rem +} + +:is(img, svg, video).responsive { + inline-size: 100%; + block-size: 100%; + margin: 0 auto +} + +:is(button, .button, .chip):not(.transparent)>.responsive { + border: .25rem solid transparent +} + +:is(button.small, .button.small, .chip)>.responsive { + inline-size: 2rem +} + +:is(button, .button, .chip.medium)>.responsive { + inline-size: 2.5rem +} + +:is(button, .button, .chip).large>.responsive { + inline-size: 3rem +} + +:is(button, .button, .chip).extra>.responsive { + inline-size: 3.5rem +} + +:is(img, svg, video).responsive.tiny { + inline-size: 100%; + block-size: 4rem +} + +:is(img, svg, video).responsive.small { + inline-size: 100%; + block-size: 8rem +} + +:is(img, svg, video).responsive.medium { + inline-size: 100%; + block-size: 12rem +} + +:is(img, svg, video).responsive.large { + inline-size: 100%; + block-size: 16rem +} + +:is(img, svg, video).responsive.extra { + inline-size: 100%; + block-size: 20rem +} + +:is(img, svg, video).responsive.round { + border-radius: 2rem +} + +:is(img, svg, video).empty-state { + max-inline-size: 100%; + inline-size: 24rem +} + +:is(button, .button, .chip, .field)>:is(img, svg):not(.responsive, .tiny, .small, .medium, .large, .extra), +:is(.tabs) :is(img, svg):not(.responsive, .tiny, .small, .medium, .large, .extra) { + min-inline-size: 1.5rem; + max-inline-size: 1.5rem; + min-block-size: 1.5rem; + max-block-size: 1.5rem +} + +:is(button, .button, .chip)>:is(i, img, svg), +:is(button, .button, .chip)>.responsive { + margin: 0 -.5rem +} + +:is(button, .button)>.responsive { + margin-inline-start: -1.5rem +} + +:is(button, .button)>span+.responsive { + margin-inline-start: -.5rem; + margin-inline-end: -1.5rem +} + +.chip>.responsive { + margin-inline-start: -1rem +} + +.chip>span+.responsive { + margin-inline-start: -.5rem; + margin-inline-end: -1rem +} + +:is(.circle, .square)>.responsive { + margin: 0 +} + +.extend>:is(.responsive, i) { + margin: 0; + position: absolute; + inset-inline: 1rem; + z-index: 1 +} + +.extend>.responsive { + inset-inline: 0; + inline-size: 3.5rem +} + +.extend.border>.responsive { + inline-size: 3.375rem +} + +menu { + opacity: 0; + visibility: hidden; + position: absolute; + box-shadow: var(--elevate2); + background-color: var(--surface-container); + z-index: 11; + inset: auto auto 0 0; + inline-size: 100%; + max-block-size: 50vh; + max-inline-size: none !important; + overflow-x: hidden; + overflow-y: auto; + font-size: .875rem; + font-weight: 400; + text-transform: none; + color: var(--on-surface); + line-height: normal; + text-align: start; + border-radius: .25rem; + transform: scale(.8) translateY(120%); + transition: var(--speed2) all, 0s background-color +} + +menu.no-wrap { + inline-size: max-content; + white-space: nowrap !important +} + +menu.active, +menu:not([data-ui]):active, +:not([data-ui]):focus-within>menu { + opacity: 1; + visibility: visible; + transform: scale(1) translateY(100%) +} + +menu.left { + inset: auto 0 0 auto +} + +menu * { + white-space: inherit !important +} + +menu>a { + padding: .75rem 1rem +} + +menu>a:not(.row) { + display: block +} + +menu>a:is(:hover, :focus, .active) { + background-color: var(--active) +} + +menu.min { + inset: 0 auto auto auto; + transform: none !important; + border-radius: inherit +} + +menu.max { + position: fixed; + inset: 0; + block-size: 100%; + max-block-size: none; + min-block-size: auto; + z-index: 100; + transform: none !important +} + +menu.no-wrap:is(.min, .max) { + min-inline-size: 16rem +} + +nav, +.row, +nav.drawer>:is(a, label), +nav.drawer :is(summary, details)>:is(a, label) { + display: flex; + align-items: center; + align-self: normal; + text-align: start; + justify-content: flex-start; + white-space: nowrap; + gap: 1rem +} + +:not(.divider, .small-divider, .medium-divider, .large-divider)+nav:not(.left, .right, .top, .bottom), +:not(.divider, .small-divider, .medium-divider, .large-divider)+.row:not(a) { + margin-block-start: 1rem +} + +:is(nav, .row)>*, +:is(nav, .row)>:not(.tooltip, menu)>* { + margin-block: 0 +} + +nav>*, +.row>* { + margin: 0 !important; + white-space: normal; + flex: none +} + +:is(nav, .row).no-space { + gap: 0 +} + +:is(nav, .row).no-space>.border+.border { + border-inline-start: 0 +} + +:is(nav, .row).medium-space { + gap: 1.5rem +} + +:is(nav, .row).large-space { + gap: 2rem +} + +nav>.max, +.row>.max, +nav.drawer>:is(a, label)>.max, +nav.drawer :is(summary, details)>:is(a, label)>.max { + flex: auto +} + +nav.wrap, +.row.wrap { + display: flex; + flex-wrap: wrap +} + +header>:is(nav, .row) { + min-block-size: 4rem +} + +footer>:is(nav, .row) { + min-block-size: 5rem +} + +nav>header>:is(nav, .row) { + margin-block-start: -.5rem !important +} + +:is(nav, .row)>.border.no-margin+.border.no-margin { + border-inline-start: 0 +} + +nav:is(.left, .right, .top, .bottom) { + border: 0; + position: fixed; + color: var(--on-surface); + transform: none; + z-index: 100; + block-size: auto; + inline-size: auto; + text-align: center; + padding: .5rem +} + +nav:is(.left, .right) { + inline-size: 5rem; + justify-content: flex-start; + flex-direction: column; + background-color: var(--surface) +} + +nav:is(.top, .bottom) { + block-size: 5rem; + justify-content: center; + flex-direction: row; + background-color: var(--surface-container) +} + +nav.top { + inset: 0 0 auto 0 +} + +nav.left { + inset: 0 auto 0 0 +} + +nav.right { + inset: 0 0 0 auto +} + +nav.bottom { + inset: auto 0 0 0 +} + +nav.drawer { + flex-direction: column; + align-items: normal; + inline-size: 20rem; + gap: 0; + padding: .5rem 1rem +} + +nav.drawer:is(.min, .max) { + inline-size: auto +} + +nav.drawer.max { + inline-size: 100% +} + +nav>header { + padding: 0; + background-color: inherit; + block-size: 4rem +} + +nav.drawer>header { + block-size: 4.5rem; + align-self: start +} + +nav.drawer:not(.left, .right)>header { + align-self: stretch +} + +nav.drawer>:is(a, label), +nav.drawer :is(summary, details)>a, +a.row.wave { + padding: .75rem; + font-size: inherit +} + +nav.drawer>a, +nav.drawer :is(summary, details)>a { + border-radius: 2rem +} + +nav.drawer>a:is(:hover, .active), +nav.drawer :is(summary, details)>a:is(:hover, .active) { + background-color: var(--secondary-container) +} + +nav.drawer>a:is(:hover, :focus, .active)>i, +nav.drawer :is(summary, details)>a:is(:hover, :focus, .active)>i { + font-variation-settings: "FILL" 1 +} + +nav:is(.left, .right, .top, .bottom):not(.drawer)>a:not(button, .button, .chip, img, video, svg) { + text-align: center; + display: flex; + flex-direction: column +} + +nav:is(.top, .bottom):not(.drawer)>a:not(button, .button, .chip, img, video, svg) { + inline-size: 3.5rem +} + +nav:is(.left, .right, .top, .bottom):not(.drawer)>a:not(button, .button, .chip)>i { + padding: .25rem; + border-radius: 2rem; + transition: var(--speed1) padding linear; + margin: 0 auto +} + +nav:is(.left, .right, .top, .bottom):not(.drawer)>a:not(button, .button, .chip):is(:hover, :focus, .active)>i { + background-color: var(--secondary-container); + color: var(--on-secondary-container); + padding: .25rem 1rem; + font-variation-settings: "FILL" 1 +} + +nav.left-align, +nav.top-align { + justify-content: flex-start +} + +nav.right-align, +nav.bottom-align { + justify-content: flex-end +} + +nav.center-align, +nav.middle-align { + justify-content: center +} + +nav:not(.left, .right)>.space { + inline-size: .5rem +} + +nav:not(.left, .right)>.medium-space { + inline-size: 1rem +} + +nav:not(.left, .right)>.large-space { + inline-size: 1.5rem +} + +@media only screen and (max-width: 600px) { + + nav.top, + nav.bottom { + justify-content: space-around + } +} + +.overlay { + opacity: 0; + visibility: hidden; + position: fixed; + inset: 0 auto auto 0; + inline-size: 100%; + block-size: 100%; + color: var(--on-surface); + background-color: var(--overlay); + z-index: 100; + transition: var(--speed3) all, 0s background-color +} + +nav>.overlay { + z-index: 0 +} + +.overlay.active { + opacity: 1; + visibility: visible +} + +.page, +:is(.page, dialog):not(.active) .page.active { + ---transform: translate(0, 0); + opacity: 0; + position: absolute; + display: none +} + +.page.active { + opacity: 1; + position: inherit; + display: inherit; + animation: var(--speed4) to-page ease +} + +.page.active.top { + ---transform: translate(0, -4rem) +} + +.page.active.bottom { + ---transform: translate(0, 4rem) +} + +.page.active.left { + ---transform: translate(-4rem, 0) +} + +[dir=rtl] .page.active.left, +.page.active.right { + ---transform: translate(4rem, 0) +} + +[dir=rtl] .page.active.right { + ---transform: translate(-4rem, 0) +} + +@keyframes to-page { + 0% { + opacity: 0; + transform: var(---transform) + } + + to { + opacity: 1; + transform: translate(0) + } +} + +progress { + position: relative; + inline-size: 100%; + block-size: .5rem; + color: var(--primary); + background: var(--surface-container-highest); + border-radius: 0; + flex: none; + border: none +} + +progress.small { + inline-size: 4rem +} + +progress.medium { + inline-size: 8rem +} + +progress.large { + inline-size: 12rem +} + +progress:not(.circle, [value]):after { + content: ""; + position: absolute; + inset: 0; + inline-size: 100%; + block-size: 100%; + clip-path: none; + background: currentColor; + animation: 1.6s to-linear ease infinite +} + +progress:not(.circle, [value])::-moz-progress-bar { + animation: 1.6s to-linear ease infinite +} + +progress:not(.circle, [value])::-webkit-progress-value { + animation: 1.6s to-linear ease infinite +} + +progress::-webkit-progress-bar { + background: none +} + +progress::-webkit-progress-value { + background: currentColor +} + +progress::-moz-progress-bar { + background: currentColor +} + +progress.circle { + display: inline-block; + inline-size: 2.5rem; + block-size: 2.5rem; + border-radius: 50%; + border-width: .3rem; + border-style: solid; + border-color: currentColor; + animation: 1.6s to-circular linear infinite; + background: none; + flex: none +} + +progress.circle::-moz-progress-bar { + background: none +} + +progress.circle.small { + inline-size: 1.5rem; + block-size: 1.5rem; + border-width: .2rem +} + +progress.circle.large { + inline-size: 3.5rem; + block-size: 3.5rem; + border-width: .4rem +} + +:is(nav, .row, .field)>progress:not(.circle, .small, .medium, .large) { + flex: auto +} + +@keyframes to-linear { + 0% { + margin-inline-start: 0%; + inline-size: 0% + } + + 50% { + margin-inline-start: 10%; + inline-size: 80% + } + + to { + margin-inline-start: 100%; + inline-size: 0% + } +} + +@keyframes to-circular { + 0% { + transform: rotate(0); + clip-path: polygon(50% 50%, 0% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%) + } + + 20% { + clip-path: polygon(50% 50%, 0% 0%, 50% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%) + } + + 30% { + clip-path: polygon(50% 50%, 0% 0%, 50% 0%, 100% 0%, 100% 50%, 100% 50%, 100% 50%, 100% 50%, 100% 50%) + } + + 40% { + clip-path: polygon(50% 50%, 0% 0%, 50% 0%, 100% 0%, 100% 50%, 100% 100%, 100% 100%, 100% 100%, 100% 100%) + } + + 50% { + clip-path: polygon(50% 50%, 50% 0%, 50% 0%, 100% 0%, 100% 50%, 100% 100%, 50% 100%, 50% 100%, 50% 100%) + } + + 60% { + clip-path: polygon(50% 50%, 100% 50%, 100% 50%, 100% 50%, 100% 50%, 100% 100%, 50% 100%, 0% 100%, 0% 100%) + } + + 70% { + clip-path: polygon(50% 50%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 0% 100%, 0% 50%) + } + + 80% { + clip-path: polygon(50% 50%, 0% 100%, 0% 100%, 0% 100%, 0% 100%, 0% 100%, 0% 100%, 0% 100%, 0% 50%) + } + + 90% { + transform: rotate(360deg); + clip-path: polygon(50% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%) + } + + to { + clip-path: polygon(50% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%) + } +} + +.checkbox, +.radio, +.switch { + direction: ltr; + inline-size: auto; + block-size: auto; + line-height: normal; + white-space: nowrap; + cursor: pointer; + display: inline-flex; + align-items: center +} + +:is(.checkbox, .radio)>input { + inline-size: 1.5rem; + block-size: 1.5rem; + opacity: 0 +} + +.switch>input { + inline-size: 3.25rem; + block-size: 2rem; + opacity: 0 +} + +:is(.checkbox, .radio, .switch)>span { + display: inline-flex; + align-items: center; + color: var(--on-surface); + font-size: .875rem +} + +:is(.checkbox, .radio)>span:not(:empty) { + padding-inline-start: .25rem +} + +:is(.checkbox, .radio, .switch)>span:before, +.icon>span>i { + font-family: var(--font-icon); + font-weight: 400; + font-style: normal; + font-size: 1.5rem; + line-height: 1; + letter-spacing: normal; + text-transform: none; + display: inline-block; + white-space: nowrap; + word-wrap: normal; + direction: ltr; + font-feature-settings: "liga"; + -webkit-font-smoothing: antialiased; + vertical-align: middle; + text-align: center; + overflow: hidden; + inline-size: 1.5rem; + block-size: 1.5rem; + box-sizing: border-box; + margin: 0 auto; + outline: none; + color: var(--primary); + position: absolute; + inset: auto auto auto -1.5rem; + background-color: transparent; + border-radius: 50%; + user-select: none; + z-index: 1; + box-shadow: 0 0 0 0 var(--active); + transition: var(--speed1) all +} + +.switch>span:before, +.switch.icon>span>i { + position: absolute; + inset: 50% auto auto 0; + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: 50%; + transition: var(--speed2) all; + font-size: 1rem; + user-select: none; + min-inline-size: auto; + content: ""; + color: var(--surface-variant); + background-color: var(--outline) +} + +.switch>span:before, +.switch.icon>span>i { + transform: translate(-3rem, -50%) scale(.6) +} + +.switch.icon>span>i { + transform: translate(-3rem, -50%) scale(1) +} + +.checkbox>span:before { + content: "check_box_outline_blank" +} + +.radio>span:before { + content: "radio_button_unchecked" +} + +.checkbox>input:checked+span:before { + content: "check_box"; + font-variation-settings: "FILL" 1 +} + +.radio>input:checked+span:before { + content: "radio_button_checked" +} + +:is(.radio, .checkbox, .switch).icon>span:before { + content: "" !important; + font-variation-settings: unset !important +} + +:is(.checkbox, .radio)>input:not(:disabled):is(:focus, :hover)+span:before { + background-color: var(--active); + box-shadow: 0 0 0 .5rem var(--active) +} + +.switch>input:not(:disabled):is(:focus, :hover)+span:before, +.switch.icon>input:not(:disabled):is(:focus, :hover)+span>i { + box-shadow: 0 0 0 .5rem var(--active) +} + +:is(.checkbox, .radio)>input:checked+span:before, +:is(.checkbox, .radio).icon>input:checked+span>i { + color: var(--primary) +} + +.icon>input:checked+span>i:first-child, +.icon>span>i:last-child { + opacity: 0 +} + +.icon>input:checked+span>i:last-child, +.icon>span>i:first-child { + opacity: 1 +} + +.switch>input:checked+span:after { + border: none; + background-color: var(--primary) +} + +.switch>input:checked+span:before, +.switch.icon>input:checked+span>i { + content: "check"; + color: var(--primary); + background-color: var(--on-primary) +} + +.switch>input:checked+span:before, +.switch.icon>input:checked+span>i { + transform: translate(-1.75rem, -50%) scale(1) +} + +:is(.checkbox, .radio, .switch)>input:disabled+span { + opacity: .5; + cursor: not-allowed +} + +.checkbox+.checkbox, +.radio+.radio, +.switch+.switch { + margin-inline-start: .5rem +} + +.switch>span:after { + content: ""; + position: absolute; + inset: 50% auto auto 0; + background-color: var(--active); + border: .125rem solid var(--outline); + box-sizing: border-box; + inline-size: 3.25rem; + block-size: 2rem; + border-radius: 2rem +} + +.switch>span:after { + transform: translate(-3.25rem, -50%) +} + +.field>:is(nav, .row) { + flex-grow: 1; + padding: 0 1rem +} + +.field.round>:is(nav, .row) { + flex-grow: 1; + padding: 0 1.5rem +} + +.slider { + ---start: 0%; + ---end: 0%; + ---value1: ""; + ---value2: ""; + display: flex; + align-items: center !important; + inline-size: auto; + block-size: 1.25rem; + margin: 1.125rem; + flex: none +} + +.slider.vertical { + flex-direction: row !important; + margin: .5rem auto !important; + padding: 50% 0; + transform: rotate(-90deg); + inline-size: 100% +} + +.slider.small { + inline-size: 4rem +} + +.slider.medium { + inline-size: 8rem +} + +.slider.large { + inline-size: 12rem +} + +.slider>input { + appearance: none; + box-shadow: none; + border: none; + outline: none; + pointer-events: none; + inline-size: 100%; + block-size: .25rem; + background: none; + z-index: 1; + padding: 0; + margin: 0 +} + +.slider>input:focus~.tooltip { + visibility: visible +} + +.slider>input:only-of-type { + cursor: pointer; + pointer-events: all +} + +.slider>input+input { + position: absolute +} + +.slider>input::-webkit-slider-thumb { + appearance: none; + box-shadow: none; + border: none; + outline: none; + pointer-events: all; + block-size: 1.25rem; + inline-size: 1.25rem; + border-radius: 50%; + background: var(--primary); + transition: var(--speed1) all ease-out; + cursor: pointer +} + +.slider>input::-moz-range-thumb { + appearance: none; + box-shadow: none; + border: none; + outline: none; + pointer-events: all; + block-size: 1.25rem; + inline-size: 1.25rem; + border-radius: 50%; + background: var(--primary); + transition: var(--speed1) all ease-out; + cursor: pointer +} + +.slider>input:not(:disabled):is(:focus, :hover)::-webkit-slider-thumb { + box-shadow: 0 0 0 .625rem var(--active) +} + +.slider>input:not(:disabled):is(:focus, :hover)::-moz-range-thumb { + box-shadow: 0 0 0 .625rem var(--active) +} + +.slider>input:disabled { + cursor: not-allowed; + opacity: 1 +} + +.slider>input:disabled::-webkit-slider-thumb { + background: #9E9E9E; + cursor: not-allowed +} + +.slider>input:disabled::-moz-range-thumb { + background: #9E9E9E; + cursor: not-allowed +} + +.slider>input:disabled~:is(span, .tooltip) { + background: #9E9E9E +} + +.slider>span { + position: absolute; + block-size: .375rem; + border-radius: 1rem; + background: var(--primary); + z-index: 0; + inset: calc(50% - .1875rem) var(---end) auto var(---start) +} + +.field>.slider { + inline-size: 100% +} + +.slider:before { + content: ""; + position: absolute; + inline-size: 100%; + block-size: .25rem; + border-radius: 1rem; + background: var(--active) +} + +.slider>.tooltip { + opacity: 0; + inset: .25rem auto auto calc(100% - var(---end)); + inline-size: 1.75rem; + block-size: 1.75rem; + background-color: var(--primary); + border-radius: 50% 50% 0; + transition: var(--speed2) ease top, var(--speed2) ease opacity; + transform: translate(-50%, -50%) rotate(45deg) !important +} + +[dir=rtl] .slider>.tooltip { + transform: translate(50%, -50%) rotate(45deg) !important +} + +.slider>.tooltip+.tooltip { + inset: .25rem calc(100% - var(---start)) auto auto; + transform: translate(50%, -50%) rotate(45deg) !important +} + +[dir=rtl] .slider>.tooltip+.tooltip { + transform: translate(-50%, -50%) rotate(45deg) !important +} + +.slider>.tooltip:before { + content: var(---value1); + transform: rotate(-45deg) +} + +.slider>.tooltip+.tooltip:before { + content: var(---value2) +} + +.slider:hover>.tooltip { + inset-block-start: -.25rem; + opacity: 1 +} + +.slider.vertical>.tooltip { + display: none +} + +:is(nav, .row, .field)>.slider:not(.circle, .small, .medium, .large) { + flex: auto +} + +.snackbar { + ---transform-start: translate(-50%, 1rem); + ---transform-end: translate(-50%, 0); + position: fixed; + inset: auto auto 6rem 50%; + inline-size: 80%; + block-size: auto; + z-index: 200; + visibility: hidden; + display: flex; + box-shadow: var(--elevate2); + color: var(--inverse-on-surface); + background-color: var(--inverse-surface); + padding: 1rem; + opacity: 1; + cursor: pointer; + text-align: start; + align-items: center; + border-radius: .25rem; + gap: .5rem; + transform: var(---transform-end) +} + +[dir=rtl] .snackbar { + ---transform-start: translate(50%, 1rem); + ---transform-end: translate(50%, 0) +} + +.snackbar.top { + inset: 6rem auto auto 50% +} + +.snackbar.active { + visibility: visible; + animation: var(--speed2) to-snackbar +} + +.snackbar.active.top { + ---transform-end: translate(-50%, -1rem) +} + +[dir=rtl] .snackbar.active.top { + ---transform-end: translate(50%, -1rem) +} + +.snackbar>.max { + flex: auto +} + +@keyframes to-snackbar { + 0% { + opacity: 0; + transform: var(---transform-start) + } + + to { + opacity: 1; + transform: var(---transform-end) + } +} + +@media only screen and (min-width: 993px) { + .snackbar { + inline-size: 40% + } +} + +table { + ---stripes: rgb(0 0 0 / .05); + inline-size: 100%; + border-spacing: 0; + font-size: .875rem; + color: var(--on-surface); + text-align: start; + background-color: var(--surface) +} + +.dark table { + ---stripes: rgb(255 255 255 / .05) +} + +table :is(thead, tbody, tfoot, tr, th) { + background-color: inherit +} + +:is(th, td) { + /* inline-size: auto; */ + /* max-inline-size: 1rem; */ + text-align: inherit; + padding: .5rem; +} + +:is(th, td)>* { + vertical-align: middle; + z-index: 0 +} + + +table.border>tbody>tr:not(:last-child)>td, +thead>tr>th { + border-block-end: .0625rem solid rgba(255, 255, 255, .5) +} + +tfoot>tr>th { + border-block-start: .0625rem solid rgba(255, 255, 255, .5) +} + +table.stripes>tbody>tr:nth-child(odd) { + background-color: var(---stripes) +} + +table.no-space :is(th, td) { + padding: 0 +} + +table.medium-space :is(th, td) { + padding: .75rem +} + +table.large-space :is(th, td) { + padding: 1rem +} + +table>.fixed, +th.fixed { + position: sticky; + z-index: 1; + inset-block-start: 0 +} + +tfoot.fixed, +tfoot th.fixed { + inset-block-end: 0 +} + +:is(td, th).min { + inline-size: 0; + max-inline-size: 0%; + white-space: nowrap +} + + + +.tabs { + display: flex; + white-space: nowrap; + border-block-end: .0625rem solid var(--surface-variant) +} + +.tabs.min { + padding: 0 1rem; + gap: 2rem +} + +.tabs:not(.left-align, .right-align, .center-align) { + justify-content: space-around +} + +*+.tabs { + margin-block-start: 1rem +} + +.tabs>a { + display: flex; + font-size: .875rem; + font-weight: 500; + color: var(--on-surface-variant); + padding: .5rem 1rem; + border-block-end: .125rem solid transparent; + text-align: center; + min-block-size: 3rem; + inline-size: 100%; + gap: .25rem +} + +.tabs.min>a { + inline-size: auto; + padding: .5rem 0 +} + +.tabs.small>a { + min-block-size: 2rem +} + +.tabs.large>a { + min-block-size: 4rem +} + +.tabs>a.active { + color: var(--primary); + border-block-end: .125rem solid var(--primary) +} + +.tabs>a.active>i { + color: var(--primary) +} + +.tabs:is(.left-align, .center-align, .right-align)>a { + inline-size: auto +} + +.tooltip { + ---space: -.5rem; + visibility: hidden; + display: flex; + align-items: center; + justify-content: center; + gap: .5rem; + background-color: var(--inverse-surface); + color: var(--inverse-on-surface); + font-size: .75rem; + text-align: center; + border-radius: .25rem; + padding: .5rem; + position: absolute; + z-index: 3; + inset: 0 auto auto 50%; + inline-size: auto; + white-space: nowrap; + font-weight: 500; + opacity: 0; + transition: var(--speed2) all; + line-height: normal; + transform: translate(-50%, -100%) scale(.9); + overflow: visible; +} + +[dir=rtl] .tooltip { + transform: translate(50%, -100%) scale(.9) +} + +.tooltip.left { + inset: 50% auto auto 0; + transform: translate(-100%, -50%) scale(.9) +} + +[dir=rtl] .tooltip.left { + transform: translate(100%, -50%) scale(.9) +} + +.tooltip.right { + inset: 50% 0 auto auto; + transform: translate(100%, -50%) scale(.9) +} + +[dir=rtl] .tooltip.right { + transform: translate(-100%, -50%) scale(.9) +} + +.tooltip.bottom { + inset: auto auto 0 50%; + transform: translate(-50%, 100%) scale(.9) +} + +[dir=rtl] .tooltip.bottom { + transform: translate(50%, 100%) scale(.9) +} + +.tooltip.small { + inline-size: 8rem; + white-space: normal +} + +.tooltip.medium { + inline-size: 12rem; + white-space: normal +} + +.tooltip.large { + inline-size: 16rem; + white-space: normal +} + +:hover>.tooltip { + visibility: visible; + opacity: 1; + transform: translate(-50%, -100%) scale(1) +} + +[dir=rtl] :hover>.tooltip { + transform: translate(50%, -100%) scale(1) +} + +:hover>.tooltip.left { + transform: translate(-100%, -50%) scale(1) +} + +[dir=rtl] :hover>.tooltip.left { + transform: translate(100%, -50%) scale(1) +} + +:hover>.tooltip.right { + transform: translate(100%, -50%) scale(1) +} + +[dir=rtl] :hover>.tooltip.right { + transform: translate(-100%, -50%) scale(1) +} + +:hover>.tooltip.bottom { + transform: translate(-50%, 100%) scale(1) +} + +[dir=rtl] :hover>.tooltip.bottom { + transform: translate(50%, 100%) scale(1) +} + +.tooltip.no-space { + ---space: 0 +} + +.tooltip.medium-space { + ---space: -1rem +} + +.tooltip.large-space { + ---space: -1.5rem +} + +.tooltip:not(.left, .right, .bottom) { + margin-block-start: var(---space) !important +} + +.tooltip.left { + margin-inline-start: var(---space) !important +} + +.tooltip.right { + margin-inline-end: var(---space) !important +} + +.tooltip.bottom { + margin-block-end: var(---space) !important +} + +menu:active~.tooltip, +:is(button, .button):focus>menu~.tooltip, +.field>:focus~menu~.tooltip { + visibility: hidden +} + +.slider>.tooltip { + ---space: -1.25rem +} + +.slider.vertical>.tooltip { + ---space: -.75rem +} + +.slider.vertical>.tooltip:is(.left, .right) { + ---space: -.5rem +} + +.tooltip.max { + display: block; + font-size: inherit; + white-space: normal; + text-align: start; + inline-size: 20rem; + border-radius: .5rem; + padding: 1rem; + box-shadow: var(--elevate2) +} + +:is(.blur, .small-blur, .medium-blur, .large-blur), +:is(.blur, .small-blur, .medium-blur, .large-blur).light { + ---blur: 1rem; + -webkit-backdrop-filter: blur(var(---blur)); + backdrop-filter: blur(var(---blur)); + color: var(--on-surface); + background-color: #ffffff80 +} + +.dark :is(.blur, .small-blur, .medium-blur, .large-blur), +:is(.blur, .small-blur, .medium-blur, .large-blur).dark { + background-color: #00000080 +} + +.small-blur { + ---blur: .5rem +} + +.large-blur { + ---blur: 1.5rem +} + +.shadow { + background-color: #00000050 +} + +:is(.left-shadow, .right-shadow, .top-shadow, .bottom-shadow) { + background-color: transparent !important +} + +.left-shadow { + background-image: linear-gradient(to right, black, transparent) +} + +.right-shadow { + background-image: linear-gradient(to left, black, transparent) +} + +.bottom-shadow { + background-image: linear-gradient(to top, black, transparent) +} + +.top-shadow { + background-image: linear-gradient(to bottom, black, transparent) +} + +tr:hover { + background-color: var(--secondary-container) !important; +} + +.mask { + visibility: visible !important; +} \ No newline at end of file diff --git a/assets/beer.min.js b/assets/beer.min.js new file mode 100644 index 0000000..3305dcd --- /dev/null +++ b/assets/beer.min.js @@ -0,0 +1,437 @@ +export default (() => { + let m, $, N, P; + const l = { light: "", dark: "" }, + R = []; + async function Q(t) { + return await new Promise((n) => setTimeout(n, t)); + } + function U() { + return "fxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (t) => { + const n = (Math.random() * 16) | 0; + return (t === "x" ? n : (n & 3) | 8).toString(16); + }); + } + function b(t, n) { + try { + return typeof t == "string" + ? (n != null ? n : document).querySelector(t) + : t; + } catch { + return null; + } + } + function f(t, n) { + try { + return typeof t == "string" + ? (n != null ? n : document).querySelectorAll(t) + : t != null + ? t + : R; + } catch { + return R; + } + } + function d(t, n) { + var e, r; + return (r = + (e = t == null ? void 0 : t.classList) == null + ? void 0 + : e.contains(n)) != null + ? r + : !1; + } + function L(t, n) { + var e; + return ( + ((e = t == null ? void 0 : t.tagName) == null + ? void 0 + : e.toLowerCase()) === n + ); + } + function k(t, n) { + var e; + return ( + ((e = t == null ? void 0 : t.type) == null ? void 0 : e.toLowerCase()) === + n + ); + } + function v(t, n) { + var e; + (e = t == null ? void 0 : t.classList) == null || e.add(n); + } + function u(t, n) { + var e; + (e = t == null ? void 0 : t.classList) == null || e.remove(n); + } + function g(t, n, e) { + t == null || t.addEventListener(n, e, !0); + } + function X(t, n, e) { + t == null || t.removeEventListener(n, e, !0); + } + function Y(t, n) { + var e; + (e = n == null ? void 0 : n.parentNode) == null || e.insertBefore(t, n); + } + function _(t) { + return t == null ? void 0 : t.previousElementSibling; + } + function j(t) { + return t == null ? void 0 : t.nextElementSibling; + } + function x(t) { + return t == null ? void 0 : t.parentElement; + } + function J(t) { + const n = document.createElement("div"); + for (const e in t) n.setAttribute(e, t[e]); + return n; + } + function T(t) { + const n = t; + k(n, "number") && !n.value && (n.value = ""), + n.placeholder || (n.placeholder = " "), + t.getAttribute("data-ui") && q(t, null); + } + function tt(t) { + q(t.currentTarget, null, null, t); + } + function nt(t) { + const n = t.currentTarget, + e = x(n), + r = b( + "input:not([type=file], [type=checkbox], [type=radio]), select, textarea", + e + ); + r && r.focus(); + } + function et(t) { + const n = t.currentTarget; + T(n); + } + function rt(t) { + const n = t.currentTarget; + T(n); + } + function W(t) { + X(document.body, "click", W); + const n = t.target; + f("menu.active").forEach((r) => V(n, r, t)); + } + function at(t) { + const n = t.currentTarget; + u(n, "active"), m && clearTimeout(m); + } + function it(t) { + const n = t.currentTarget; + D(n); + } + function ot(t) { + const n = t.currentTarget; + I(n); + } + function ct(t) { + const n = t.currentTarget; + D(n, t); + } + function ut(t) { + const n = t.currentTarget; + I(n, t); + } + function st(t) { + const n = t.currentTarget; + G(n); + } + function Z() { + $ && clearTimeout($), + ($ = setTimeout(() => { + A(); + }, 180)); + } + function D(t, n) { + if (n && n.key === "Enter") { + const i = _(t); + return k(i, "file") ? i.click() : void 0; + } + const e = t, + r = j(t); + !k(r, "text") || + ((r.value = e.files + ? Array.from(e.files) + .map((i) => i.name) + .join(", ") + : ""), + (r.readOnly = !0), + r.addEventListener("keydown", ct), + T(r)); + } + function I(t, n) { + if (n && n.key === "Enter") { + const i = _(t); + return k(i, "color") ? i.click() : void 0; + } + const e = t, + r = j(t); + !k(r, "text") || + ((r.readOnly = !0), + (r.value = e.value), + r.addEventListener("keydown", ut), + T(r)); + } + function G(t) { + const n = x(t), + e = b("span", n), + r = f("input", n); + if (!r.length || !e) return; + const i = + parseInt( + getComputedStyle(document.documentElement).getPropertyValue("--size") + ) || 16, + c = (1.25 * i * 100) / r[0].offsetWidth, + o = [], + s = []; + for (let y = 0; y < r.length; y++) { + const z = parseFloat(r[y].min), + B = parseFloat(r[y].max), + O = parseFloat(r[y].value), + C = z || 0, + F = B || 100, + w = O || 0, + K = ((w - C) * 100) / (F - C), + H = c / 2 - (c * K) / 100; + o.push(K + H), + s.push(w), + z !== C && (r[y].min = `${C}`), + B !== F && (r[y].max = `${F}`), + O !== w && (r[y].value = `${w}`); + } + let a = o[0], + p = 0, + h = 100 - p - a, + S = s[0], + M = s[1] || 0; + r.length > 1 && + ((a = Math.abs(o[1] - o[0])), + (p = o[1] > o[0] ? o[0] : o[1]), + (h = 100 - p - a), + M > S && ((S = s[1] || 0), (M = s[0]))), + n.style.setProperty("---start", `${p}%`), + n.style.setProperty("---end", `${h}%`), + n.style.setProperty("---value1", `'${S}'`), + n.style.setProperty("---value2", `'${M}'`); + } + async function q(t, n, e, r) { + if (!(!n && ((n = b(t.getAttribute("data-ui"))), !n))) { + if (L(n, "dialog")) return await ft(t, n); + if (L(n, "menu")) return V(t, n, r); + if (d(n, "snackbar")) return dt(t, n, e); + if (d(n, "page")) return lt(t, n); + if ((E(t), d(n, "active"))) return u(n, "active"); + v(n, "active"); + } + } + function E(t) { + const n = x(t); + if (!d(n, "tabs")) return; + f("a", n).forEach((r) => u(r, "active")), v(t, "active"); + } + function lt(t, n) { + E(t); + const e = x(n); + if (e) + for (let r = 0; r < e.children.length; r++) + d(e.children[r], "page") && u(e.children[r], "active"); + v(n, "active"); + } + function V(t, n, e) { + N && clearTimeout(N), + (N = setTimeout(() => { + var i, c; + if ((g(document.body, "click", W), E(t), d(n, "active"))) { + if (!e) return u(n, "active"); + const o = e.target, + s = b((i = o.getAttribute("data-ui")) != null ? i : ""), + a = o.closest("menu"), + p = !b("menu", (c = o.closest("[data-ui]")) != null ? c : void 0); + return s && s !== a ? V(o, s) : !s && !p && a ? !1 : u(n, "active"); + } + f("menu.active").forEach((o) => u(o, "active")), v(n, "active"); + }, 90)); + } + async function ft(t, n) { + var a; + (a = document.activeElement) == null || a.blur(), E(t); + let e = _(n); + const r = n, + i = d(n, "active") || r.open, + c = d(n, "modal"), + o = x(n), + s = L(o, "nav"); + d(e, "overlay") || ((e = J({ class: "overlay" })), Y(e, n), await Q(90)), + (e.onclick = () => { + c || (u(t, "active"), u(n, "active"), u(e, "active"), r.close()); + }), + s && + f("dialog, a, .overlay", o).forEach((h) => { + u(h, "active"), h.open && h.close(); + }), + i + ? (u(t, "active"), u(e, "active"), u(n, "active"), r.close()) + : (!L(t, "button") && + !d(t, "button") && + !d(t, "chip") && + v(t, "active"), + v(e, "active"), + v(n, "active"), + c ? r.showModal() : r.show()); + } + function dt(t, n, e) { + var i; + (i = document.activeElement) == null || i.blur(), + E(t), + f(".snackbar.active").forEach((c) => u(c, "active")), + v(n, "active"), + g(n, "click", at), + m && clearTimeout(m), + e !== -1 && + (m = setTimeout( + () => { + u(n, "active"); + }, + e != null ? e : 6e3 + )); + } + function gt() { + if (l.light && l.dark) return l; + const t = document.createElement("body"); + (t.className = "light"), document.body.appendChild(t); + const n = document.createElement("body"); + (n.className = "dark"), document.body.appendChild(n); + const e = getComputedStyle(t), + r = getComputedStyle(n), + i = [ + "--primary", + "--on-primary", + "--primary-container", + "--on-primary-container", + "--secondary", + "--on-secondary", + "--secondary-container", + "--on-secondary-container", + "--tertiary", + "--on-tertiary", + "--tertiary-container", + "--on-tertiary-container", + "--error", + "--on-error", + "--error-container", + "--on-error-container", + "--background", + "--on-background", + "--surface", + "--on-surface", + "--surface-variant", + "--on-surface-variant", + "--outline", + "--outline-variant", + "--shadow", + "--scrim", + "--inverse-surface", + "--inverse-on-surface", + "--inverse-primary", + "--surface-dim", + "--surface-bright", + "--surface-container-lowest", + "--surface-container-low", + "--surface-container", + "--surface-container-high", + "--surface-container-highest", + ]; + for (let c = 0; c < i.length; c++) + (l.light += i[c] + ":" + e.getPropertyValue(i[c]) + ";"), + (l.dark += i[c] + ":" + r.getPropertyValue(i[c]) + ";"); + return document.body.removeChild(t), document.body.removeChild(n), l; + } + function yt(t) { + if (!t || !globalThis.materialDynamicColors) return gt(); + const n = /dark/i.test(document.body.className) ? "dark" : "light"; + return t.light && t.dark + ? ((l.light = t.light), + (l.dark = t.dark), + document.body.setAttribute("style", t[n]), + t) + : globalThis.materialDynamicColors(t).then((e) => { + const r = (i) => { + let c = ""; + for (const o in i) { + const s = o + .replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2") + .toLowerCase(), + a = i[o]; + c += "--" + s + ":" + a + ";"; + } + return c; + }; + return ( + (l.light = r(e.light)), + (l.dark = r(e.dark)), + document.body.setAttribute("style", l[n]), + l + ); + }); + } + function vt(t) { + if (!t) return /dark/i.test(document.body.className) ? "dark" : "light"; + document.body.classList.remove("light", "dark"), + document.body.classList.add(t); + const n = t === "light" ? l.light : l.dark; + return ( + globalThis.materialDynamicColors && + document.body.setAttribute("style", n), + t + ); + } + function pt() { + P || + ((P = new MutationObserver(Z)), + P.observe(document.body, { + attributes: !0, + attributeFilter: ["value", "max", "min"], + childList: !0, + subtree: !0, + }), + Z()); + } + function A(t, n) { + if (t) { + if (t === "setup") return pt(); + if (t === "guid") return U(); + if (t === "mode") return vt(n); + if (t === "theme") return yt(n); + const a = b(t); + if (!a) return; + q(a, a, n); + } + f("[data-ui]").forEach((a) => g(a, "click", tt)), + f(".field > label").forEach((a) => g(a, "click", nt)), + f( + ".field > input:not([type=file], [type=color], [type=range]), .field > select, .field > textarea" + ).forEach((a) => { + g(a, "focus", et), g(a, "blur", rt), T(a); + }), + f(".field > input[type=file]").forEach((a) => { + g(a, "change", it), D(a); + }), + f(".field > input[type=color]").forEach((a) => { + g(a, "change", ot), I(a); + }), + f(".slider > input[type=range]").forEach((a) => { + g(a, "input", st), G(a); + }); + } + globalThis.addEventListener && + globalThis.addEventListener("load", async () => await A("setup")); + globalThis.beercss = A; + globalThis.ui = A; + return globalThis.ui; +})(); diff --git a/assets/maintainscroll.js b/assets/maintainscroll.js new file mode 100644 index 0000000..a35f1ab --- /dev/null +++ b/assets/maintainscroll.js @@ -0,0 +1,25 @@ +/* + * Maintain & keep scroll position after post-back & postback & refresh. + * Just include this js file (no need for cookies). + * + * Author: Evalds Urtans + * Website: http://www.evalds.lv + */ + +document.addEventListener('DOMContentLoaded', function() { + var sep = '\uE000'; // an unusual char: unicode 'Private Use, First' + + window.addEventListener('pagehide', function(e) { + window.name += sep + window.pageXOffset + sep + window.pageYOffset; + }); + + if(window.name && window.name.indexOf(sep) > -1) + { + var parts = window.name.split(sep); + if(parts.length >= 3) + { + window.name = parts[0]; + window.scrollTo(parseFloat(parts[parts.length - 2]), parseFloat(parts[parts.length - 1])); + } + } +}); diff --git a/assets/material-dynamic-colors.min.js b/assets/material-dynamic-colors.min.js new file mode 100644 index 0000000..1b3bd81 --- /dev/null +++ b/assets/material-dynamic-colors.min.js @@ -0,0 +1,394 @@ +export default (() => { +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */function q(e) { return e < 0 ? -1 : e === 0 ? 0 : 1 } function nt(e, t, r) { return (1 - r) * e + r * t } function qt(e, t, r) { return r < e ? e : r > t ? t : r } function ht(e, t, r) { return r < e ? e : r > t ? t : r } function Ot(e) { return e = e % 360, e < 0 && (e = e + 360), e } function Dt(e) { return e = e % 360, e < 0 && (e = e + 360), e } function jt(e, t) { return Dt(t - e) <= 180 ? 1 : -1 } function Nt(e, t) { return 180 - Math.abs(Math.abs(e - t) - 180) } function bt(e, t) { const r = e[0] * t[0][0] + e[1] * t[0][1] + e[2] * t[0][2], n = e[0] * t[1][0] + e[1] * t[1][1] + e[2] * t[1][2], a = e[0] * t[2][0] + e[1] * t[2][1] + e[2] * t[2][2]; return [r, n, a] }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */const zt = [[.41233895, .35762064, .18051042], [.2126, .7152, .0722], [.01932141, .11916382, .95034478]], Yt = [[3.2413774792388685, -1.5376652402851851, -.49885366846268053], [-.9691452513005321, 1.8758853451067872, .04156585616912061], [.05562093689691305, -.20395524564742123, 1.0571799111220335]], wt = [95.047, 100, 108.883]; function ft(e, t, r) { return (255 << 24 | (e & 255) << 16 | (t & 255) << 8 | r & 255) >>> 0 } function Et(e) { const t = tt(e[0]), r = tt(e[1]), n = tt(e[2]); return ft(t, r, n) } function Wt(e) { return e >> 24 & 255 } function dt(e) { return e >> 16 & 255 } function mt(e) { return e >> 8 & 255 } function gt(e) { return e & 255 } function St(e, t, r) { const n = Yt, a = n[0][0] * e + n[0][1] * t + n[0][2] * r, o = n[1][0] * e + n[1][1] * t + n[1][2] * r, s = n[2][0] * e + n[2][1] * t + n[2][2] * r, c = tt(a), u = tt(o), h = tt(s); return ft(c, u, h) } function vt(e) { const t = $(dt(e)), r = $(mt(e)), n = $(gt(e)); return bt([t, r, n], zt) } function Jt(e, t, r) { const n = wt, a = (e + 16) / 116, o = t / 500 + a, s = a - r / 200, c = ut(o), u = ut(a), h = ut(s), l = c * n[0], d = u * n[1], p = h * n[2]; return St(l, d, p) } function Xt(e) { const t = $(dt(e)), r = $(mt(e)), n = $(gt(e)), a = zt, o = a[0][0] * t + a[0][1] * r + a[0][2] * n, s = a[1][0] * t + a[1][1] * r + a[1][2] * n, c = a[2][0] * t + a[2][1] * r + a[2][2] * n, u = wt, h = o / u[0], l = s / u[1], d = c / u[2], p = at(h), f = at(l), M = at(d), g = 116 * f - 16, b = 500 * (p - f), w = 200 * (f - M); return [g, b, w] } function $t(e) { const t = Q(e), r = tt(t); return ft(r, r, r) } function Ct(e) { const t = vt(e)[1]; return 116 * at(t / 100) - 16 } function Q(e) { return 100 * ut((e + 16) / 116) } function It(e) { return at(e / 100) * 116 - 16 } function $(e) { const t = e / 255; return t <= .040449936 ? t / 12.92 * 100 : Math.pow((t + .055) / 1.055, 2.4) * 100 } function tt(e) { const t = e / 100; let r = 0; return t <= .0031308 ? r = t * 12.92 : r = 1.055 * Math.pow(t, 1 / 2.4) - .055, qt(0, 255, Math.round(r * 255)) } function Kt() { return wt } function at(e) { const t = .008856451679035631, r = 24389 / 27; return e > t ? Math.pow(e, 1 / 3) : (r * e + 16) / 116 } function ut(e) { const t = .008856451679035631, r = 24389 / 27, n = e * e * e; return n > t ? n : (116 * e - 16) / r }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class v { static make(t = Kt(), r = 200 / Math.PI * Q(50) / 100, n = 50, a = 2, o = !1) { const s = t, c = s[0] * .401288 + s[1] * .650173 + s[2] * -.051461, u = s[0] * -.250268 + s[1] * 1.204414 + s[2] * .045854, h = s[0] * -.002079 + s[1] * .048952 + s[2] * .953127, l = .8 + a / 10, d = l >= .9 ? nt(.59, .69, (l - .9) * 10) : nt(.525, .59, (l - .8) * 10); let p = o ? 1 : l * (1 - 1 / 3.6 * Math.exp((-r - 42) / 92)); p = p > 1 ? 1 : p < 0 ? 0 : p; const f = l, M = [p * (100 / c) + 1 - p, p * (100 / u) + 1 - p, p * (100 / h) + 1 - p], g = 1 / (5 * r + 1), b = g * g * g * g, w = 1 - b, y = b * r + .1 * w * w * Math.cbrt(5 * r), k = Q(n) / t[1], A = 1.48 + Math.sqrt(k), D = .725 / Math.pow(k, .2), R = D, P = [Math.pow(y * M[0] * c / 100, .42), Math.pow(y * M[1] * u / 100, .42), Math.pow(y * M[2] * h / 100, .42)], I = [400 * P[0] / (P[0] + 27.13), 400 * P[1] / (P[1] + 27.13), 400 * P[2] / (P[2] + 27.13)], B = (2 * I[0] + I[1] + .05 * I[2]) * D; return new v(k, B, D, R, d, f, M, y, Math.pow(y, .25), A) } constructor(t, r, n, a, o, s, c, u, h, l) { this.n = t, this.aw = r, this.nbb = n, this.ncb = a, this.c = o, this.nc = s, this.rgbD = c, this.fl = u, this.fLRoot = h, this.z = l } } v.DEFAULT = v.make();/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class z { constructor(t, r, n, a, o, s, c, u, h) { this.hue = t, this.chroma = r, this.j = n, this.q = a, this.m = o, this.s = s, this.jstar = c, this.astar = u, this.bstar = h } distance(t) { const r = this.jstar - t.jstar, n = this.astar - t.astar, a = this.bstar - t.bstar, o = Math.sqrt(r * r + n * n + a * a); return 1.41 * Math.pow(o, .63) } static fromInt(t) { return z.fromIntInViewingConditions(t, v.DEFAULT) } static fromIntInViewingConditions(t, r) { const n = (t & 16711680) >> 16, a = (t & 65280) >> 8, o = t & 255, s = $(n), c = $(a), u = $(o), h = .41233895 * s + .35762064 * c + .18051042 * u, l = .2126 * s + .7152 * c + .0722 * u, d = .01932141 * s + .11916382 * c + .95034478 * u, p = .401288 * h + .650173 * l - .051461 * d, f = -.250268 * h + 1.204414 * l + .045854 * d, M = -.002079 * h + .048952 * l + .953127 * d, g = r.rgbD[0] * p, b = r.rgbD[1] * f, w = r.rgbD[2] * M, y = Math.pow(r.fl * Math.abs(g) / 100, .42), k = Math.pow(r.fl * Math.abs(b) / 100, .42), A = Math.pow(r.fl * Math.abs(w) / 100, .42), D = q(g) * 400 * y / (y + 27.13), R = q(b) * 400 * k / (k + 27.13), P = q(w) * 400 * A / (A + 27.13), I = (11 * D + -12 * R + P) / 11, B = (D + R - 2 * P) / 9, T = (20 * D + 20 * R + 21 * P) / 20, V = (40 * D + 20 * R + P) / 20, U = Math.atan2(B, I) * 180 / Math.PI, L = U < 0 ? U + 360 : U >= 360 ? U - 360 : U, Z = L * Math.PI / 180, st = V * r.nbb, K = 100 * Math.pow(st / r.aw, r.c * r.z), it = 4 / r.c * Math.sqrt(K / 100) * (r.aw + 4) * r.fLRoot, pt = L < 20.14 ? L + 360 : L, yt = .25 * (Math.cos(pt * Math.PI / 180 + 2) + 3.8), kt = 5e4 / 13 * yt * r.nc * r.ncb * Math.sqrt(I * I + B * B) / (T + .305), ct = Math.pow(kt, .9) * Math.pow(1.64 - Math.pow(.29, r.n), .73), Bt = ct * Math.sqrt(K / 100), Rt = Bt * r.fLRoot, Vt = 50 * Math.sqrt(ct * r.c / (r.aw + 4)), _t = (1 + 100 * .007) * K / (1 + .007 * K), Ft = 1 / .0228 * Math.log(1 + .0228 * Rt), Ht = Ft * Math.cos(Z), Ut = Ft * Math.sin(Z); return new z(L, Bt, K, it, Rt, Vt, _t, Ht, Ut) } static fromJch(t, r, n) { return z.fromJchInViewingConditions(t, r, n, v.DEFAULT) } static fromJchInViewingConditions(t, r, n, a) { const o = 4 / a.c * Math.sqrt(t / 100) * (a.aw + 4) * a.fLRoot, s = r * a.fLRoot, c = r / Math.sqrt(t / 100), u = 50 * Math.sqrt(c * a.c / (a.aw + 4)), h = n * Math.PI / 180, l = (1 + 100 * .007) * t / (1 + .007 * t), d = 1 / .0228 * Math.log(1 + .0228 * s), p = d * Math.cos(h), f = d * Math.sin(h); return new z(n, r, t, o, s, u, l, p, f) } static fromUcs(t, r, n) { return z.fromUcsInViewingConditions(t, r, n, v.DEFAULT) } static fromUcsInViewingConditions(t, r, n, a) { const o = r, s = n, c = Math.sqrt(o * o + s * s), h = (Math.exp(c * .0228) - 1) / .0228 / a.fLRoot; let l = Math.atan2(s, o) * (180 / Math.PI); l < 0 && (l += 360); const d = t / (1 - (t - 100) * .007); return z.fromJchInViewingConditions(d, h, l, a) } toInt() { return this.viewed(v.DEFAULT) } viewed(t) { const r = this.chroma === 0 || this.j === 0 ? 0 : this.chroma / Math.sqrt(this.j / 100), n = Math.pow(r / Math.pow(1.64 - Math.pow(.29, t.n), .73), 1 / .9), a = this.hue * Math.PI / 180, o = .25 * (Math.cos(a + 2) + 3.8), s = t.aw * Math.pow(this.j / 100, 1 / t.c / t.z), c = o * (5e4 / 13) * t.nc * t.ncb, u = s / t.nbb, h = Math.sin(a), l = Math.cos(a), d = 23 * (u + .305) * n / (23 * c + 11 * n * l + 108 * n * h), p = d * l, f = d * h, M = (460 * u + 451 * p + 288 * f) / 1403, g = (460 * u - 891 * p - 261 * f) / 1403, b = (460 * u - 220 * p - 6300 * f) / 1403, w = Math.max(0, 27.13 * Math.abs(M) / (400 - Math.abs(M))), y = q(M) * (100 / t.fl) * Math.pow(w, 1 / .42), k = Math.max(0, 27.13 * Math.abs(g) / (400 - Math.abs(g))), A = q(g) * (100 / t.fl) * Math.pow(k, 1 / .42), D = Math.max(0, 27.13 * Math.abs(b) / (400 - Math.abs(b))), R = q(b) * (100 / t.fl) * Math.pow(D, 1 / .42), P = y / t.rgbD[0], I = A / t.rgbD[1], B = R / t.rgbD[2], T = 1.86206786 * P - 1.01125463 * I + .14918677 * B, V = .38752654 * P + .62144744 * I - .00897398 * B, Y = -.0158415 * P - .03412294 * I + 1.04996444 * B; return St(T, V, Y) } static fromXyzInViewingConditions(t, r, n, a) { const o = .401288 * t + .650173 * r - .051461 * n, s = -.250268 * t + 1.204414 * r + .045854 * n, c = -.002079 * t + .048952 * r + .953127 * n, u = a.rgbD[0] * o, h = a.rgbD[1] * s, l = a.rgbD[2] * c, d = Math.pow(a.fl * Math.abs(u) / 100, .42), p = Math.pow(a.fl * Math.abs(h) / 100, .42), f = Math.pow(a.fl * Math.abs(l) / 100, .42), M = q(u) * 400 * d / (d + 27.13), g = q(h) * 400 * p / (p + 27.13), b = q(l) * 400 * f / (f + 27.13), w = (11 * M + -12 * g + b) / 11, y = (M + g - 2 * b) / 9, k = (20 * M + 20 * g + 21 * b) / 20, A = (40 * M + 20 * g + b) / 20, R = Math.atan2(y, w) * 180 / Math.PI, P = R < 0 ? R + 360 : R >= 360 ? R - 360 : R, I = P * Math.PI / 180, B = A * a.nbb, T = 100 * Math.pow(B / a.aw, a.c * a.z), V = 4 / a.c * Math.sqrt(T / 100) * (a.aw + 4) * a.fLRoot, Y = P < 20.14 ? P + 360 : P, U = 1 / 4 * (Math.cos(Y * Math.PI / 180 + 2) + 3.8), Z = 5e4 / 13 * U * a.nc * a.ncb * Math.sqrt(w * w + y * y) / (k + .305), st = Math.pow(Z, .9) * Math.pow(1.64 - Math.pow(.29, a.n), .73), K = st * Math.sqrt(T / 100), it = K * a.fLRoot, pt = 50 * Math.sqrt(st * a.c / (a.aw + 4)), yt = (1 + 100 * .007) * T / (1 + .007 * T), Mt = Math.log(1 + .0228 * it) / .0228, kt = Mt * Math.cos(I), ct = Mt * Math.sin(I); return new z(P, K, T, V, it, pt, yt, kt, ct) } xyzInViewingConditions(t) { const r = this.chroma === 0 || this.j === 0 ? 0 : this.chroma / Math.sqrt(this.j / 100), n = Math.pow(r / Math.pow(1.64 - Math.pow(.29, t.n), .73), 1 / .9), a = this.hue * Math.PI / 180, o = .25 * (Math.cos(a + 2) + 3.8), s = t.aw * Math.pow(this.j / 100, 1 / t.c / t.z), c = o * (5e4 / 13) * t.nc * t.ncb, u = s / t.nbb, h = Math.sin(a), l = Math.cos(a), d = 23 * (u + .305) * n / (23 * c + 11 * n * l + 108 * n * h), p = d * l, f = d * h, M = (460 * u + 451 * p + 288 * f) / 1403, g = (460 * u - 891 * p - 261 * f) / 1403, b = (460 * u - 220 * p - 6300 * f) / 1403, w = Math.max(0, 27.13 * Math.abs(M) / (400 - Math.abs(M))), y = q(M) * (100 / t.fl) * Math.pow(w, 1 / .42), k = Math.max(0, 27.13 * Math.abs(g) / (400 - Math.abs(g))), A = q(g) * (100 / t.fl) * Math.pow(k, 1 / .42), D = Math.max(0, 27.13 * Math.abs(b) / (400 - Math.abs(b))), R = q(b) * (100 / t.fl) * Math.pow(D, 1 / .42), P = y / t.rgbD[0], I = A / t.rgbD[1], B = R / t.rgbD[2], T = 1.86206786 * P - 1.01125463 * I + .14918677 * B, V = .38752654 * P + .62144744 * I - .00897398 * B, Y = -.0158415 * P - .03412294 * I + 1.04996444 * B; return [T, V, Y] } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class C { static sanitizeRadians(t) { return (t + Math.PI * 8) % (Math.PI * 2) } static trueDelinearized(t) { const r = t / 100; let n = 0; return r <= .0031308 ? n = r * 12.92 : n = 1.055 * Math.pow(r, 1 / 2.4) - .055, n * 255 } static chromaticAdaptation(t) { const r = Math.pow(Math.abs(t), .42); return q(t) * 400 * r / (r + 27.13) } static hueOf(t) { const r = bt(t, C.SCALED_DISCOUNT_FROM_LINRGB), n = C.chromaticAdaptation(r[0]), a = C.chromaticAdaptation(r[1]), o = C.chromaticAdaptation(r[2]), s = (11 * n + -12 * a + o) / 11, c = (n + a - 2 * o) / 9; return Math.atan2(c, s) } static areInCyclicOrder(t, r, n) { const a = C.sanitizeRadians(r - t), o = C.sanitizeRadians(n - t); return a < o } static intercept(t, r, n) { return (r - t) / (n - t) } static lerpPoint(t, r, n) { return [t[0] + (n[0] - t[0]) * r, t[1] + (n[1] - t[1]) * r, t[2] + (n[2] - t[2]) * r] } static setCoordinate(t, r, n, a) { const o = C.intercept(t[a], r, n[a]); return C.lerpPoint(t, o, n) } static isBounded(t) { return 0 <= t && t <= 100 } static nthVertex(t, r) { const n = C.Y_FROM_LINRGB[0], a = C.Y_FROM_LINRGB[1], o = C.Y_FROM_LINRGB[2], s = r % 4 <= 1 ? 0 : 100, c = r % 2 === 0 ? 0 : 100; if (r < 4) { const u = s, h = c, l = (t - u * a - h * o) / n; return C.isBounded(l) ? [l, u, h] : [-1, -1, -1] } else if (r < 8) { const u = s, h = c, l = (t - h * n - u * o) / a; return C.isBounded(l) ? [h, l, u] : [-1, -1, -1] } else { const u = s, h = c, l = (t - u * n - h * a) / o; return C.isBounded(l) ? [u, h, l] : [-1, -1, -1] } } static bisectToSegment(t, r) { let n = [-1, -1, -1], a = n, o = 0, s = 0, c = !1, u = !0; for (let h = 0; h < 12; h++) { const l = C.nthVertex(t, h); if (l[0] < 0) continue; const d = C.hueOf(l); if (!c) { n = l, a = l, o = d, s = d, c = !0; continue } (u || C.areInCyclicOrder(o, d, s)) && (u = !1, C.areInCyclicOrder(o, r, d) ? (a = l, s = d) : (n = l, o = d)) } return [n, a] } static midpoint(t, r) { return [(t[0] + r[0]) / 2, (t[1] + r[1]) / 2, (t[2] + r[2]) / 2] } static criticalPlaneBelow(t) { return Math.floor(t - .5) } static criticalPlaneAbove(t) { return Math.ceil(t - .5) } static bisectToLimit(t, r) { const n = C.bisectToSegment(t, r); let a = n[0], o = C.hueOf(a), s = n[1]; for (let c = 0; c < 3; c++)if (a[c] !== s[c]) { let u = -1, h = 255; a[c] < s[c] ? (u = C.criticalPlaneBelow(C.trueDelinearized(a[c])), h = C.criticalPlaneAbove(C.trueDelinearized(s[c]))) : (u = C.criticalPlaneAbove(C.trueDelinearized(a[c])), h = C.criticalPlaneBelow(C.trueDelinearized(s[c]))); for (let l = 0; l < 8 && !(Math.abs(h - u) <= 1); l++) { const d = Math.floor((u + h) / 2), p = C.CRITICAL_PLANES[d], f = C.setCoordinate(a, p, s, c), M = C.hueOf(f); C.areInCyclicOrder(o, r, M) ? (s = f, h = d) : (a = f, o = M, u = d) } } return C.midpoint(a, s) } static inverseChromaticAdaptation(t) { const r = Math.abs(t), n = Math.max(0, 27.13 * r / (400 - r)); return q(t) * Math.pow(n, 1 / .42) } static findResultByJ(t, r, n) { let a = Math.sqrt(n) * 11; const o = v.DEFAULT, s = 1 / Math.pow(1.64 - Math.pow(.29, o.n), .73), u = .25 * (Math.cos(t + 2) + 3.8) * (5e4 / 13) * o.nc * o.ncb, h = Math.sin(t), l = Math.cos(t); for (let d = 0; d < 5; d++) { const p = a / 100, f = r === 0 || a === 0 ? 0 : r / Math.sqrt(p), M = Math.pow(f * s, 1 / .9), b = o.aw * Math.pow(p, 1 / o.c / o.z) / o.nbb, w = 23 * (b + .305) * M / (23 * u + 11 * M * l + 108 * M * h), y = w * l, k = w * h, A = (460 * b + 451 * y + 288 * k) / 1403, D = (460 * b - 891 * y - 261 * k) / 1403, R = (460 * b - 220 * y - 6300 * k) / 1403, P = C.inverseChromaticAdaptation(A), I = C.inverseChromaticAdaptation(D), B = C.inverseChromaticAdaptation(R), T = bt([P, I, B], C.LINRGB_FROM_SCALED_DISCOUNT); if (T[0] < 0 || T[1] < 0 || T[2] < 0) return 0; const V = C.Y_FROM_LINRGB[0], Y = C.Y_FROM_LINRGB[1], U = C.Y_FROM_LINRGB[2], L = V * T[0] + Y * T[1] + U * T[2]; if (L <= 0) return 0; if (d === 4 || Math.abs(L - n) < .002) return T[0] > 100.01 || T[1] > 100.01 || T[2] > 100.01 ? 0 : Et(T); a = a - (L - n) * a / (2 * L) } return 0 } static solveToInt(t, r, n) { if (r < 1e-4 || n < 1e-4 || n > 99.9999) return $t(n); t = Dt(t); const a = t / 180 * Math.PI, o = Q(n), s = C.findResultByJ(a, r, o); if (s !== 0) return s; const c = C.bisectToLimit(o, a); return Et(c) } static solveToCam(t, r, n) { return z.fromInt(C.solveToInt(t, r, n)) } } C.SCALED_DISCOUNT_FROM_LINRGB = [[.001200833568784504, .002389694492170889, .0002795742885861124], [.0005891086651375999, .0029785502573438758, .0003270666104008398], [.00010146692491640572, .0005364214359186694, .0032979401770712076]]; C.LINRGB_FROM_SCALED_DISCOUNT = [[1373.2198709594231, -1100.4251190754821, -7.278681089101213], [-271.815969077903, 559.6580465940733, -32.46047482791194], [1.9622899599665666, -57.173814538844006, 308.7233197812385]]; C.Y_FROM_LINRGB = [.2126, .7152, .0722]; C.CRITICAL_PLANES = [.015176349177441876, .045529047532325624, .07588174588720938, .10623444424209313, .13658714259697685, .16693984095186062, .19729253930674434, .2276452376616281, .2579979360165119, .28835063437139563, .3188300904430532, .350925934958123, .3848314933096426, .42057480301049466, .458183274052838, .4976837250274023, .5391024159806381, .5824650784040898, .6277969426914107, .6751227633498623, .7244668422128921, .775853049866786, .829304845476233, .8848452951698498, .942497089126609, 1.0022825574869039, 1.0642236851973577, 1.1283421258858297, 1.1946592148522128, 1.2631959812511864, 1.3339731595349034, 1.407011200216447, 1.4823302800086415, 1.5599503113873272, 1.6398909516233677, 1.7221716113234105, 1.8068114625156377, 1.8938294463134073, 1.9832442801866852, 2.075074464868551, 2.1693382909216234, 2.2660538449872063, 2.36523901573795, 2.4669114995532007, 2.5710888059345764, 2.6777882626779785, 2.7870270208169257, 2.898822059350997, 3.0131901897720907, 3.1301480604002863, 3.2497121605402226, 3.3718988244681087, 3.4967242352587946, 3.624204428461639, 3.754355295633311, 3.887192587735158, 4.022731918402185, 4.160988767090289, 4.301978482107941, 4.445716283538092, 4.592217266055746, 4.741496401646282, 4.893568542229298, 5.048448422192488, 5.20615066083972, 5.3666897647573375, 5.5300801301023865, 5.696336044816294, 5.865471690767354, 6.037501145825082, 6.212438385869475, 6.390297286737924, 6.571091626112461, 6.7548350853498045, 6.941541251256611, 7.131223617812143, 7.323895587840543, 7.5195704746346665, 7.7182615035334345, 7.919981813454504, 8.124744458384042, 8.332562408825165, 8.543448553206703, 8.757415699253682, 8.974476575321063, 9.194643831691977, 9.417930041841839, 9.644347703669503, 9.873909240696694, 10.106627003236781, 10.342513269534024, 10.58158024687427, 10.8238400726681, 11.069304815507364, 11.317986476196008, 11.569896988756009, 11.825048221409341, 12.083451977536606, 12.345119996613247, 12.610063955123938, 12.878295467455942, 13.149826086772048, 13.42466730586372, 13.702830557985108, 13.984327217668513, 14.269168601521828, 14.55736596900856, 14.848930523210871, 15.143873411576273, 15.44220572664832, 15.743938506781891, 16.04908273684337, 16.35764934889634, 16.66964922287304, 16.985093187232053, 17.30399201960269, 17.62635644741625, 17.95219714852476, 18.281524751807332, 18.614349837764564, 18.95068293910138, 19.290534541298456, 19.633915083172692, 19.98083495742689, 20.331304511189067, 20.685334046541502, 21.042933821039977, 21.404114048223256, 21.76888489811322, 22.137256497705877, 22.50923893145328, 22.884842241736916, 23.264076429332462, 23.6469514538663, 24.033477234264016, 24.42366364919083, 24.817520537484558, 25.21505769858089, 25.61628489293138, 26.021211842414342, 26.429848230738664, 26.842203703840827, 27.258287870275353, 27.678110301598522, 28.10168053274597, 28.529008062403893, 28.96010235337422, 29.39497283293396, 29.83362889318845, 30.276079891419332, 30.722335150426627, 31.172403958865512, 31.62629557157785, 32.08401920991837, 32.54558406207592, 33.010999283389665, 33.4802739966603, 33.953417292456834, 34.430438229418264, 34.911345834551085, 35.39614910352207, 35.88485700094671, 36.37747846067349, 36.87402238606382, 37.37449765026789, 37.87891309649659, 38.38727753828926, 38.89959975977785, 39.41588851594697, 39.93615253289054, 40.460400508064545, 40.98864111053629, 41.520882981230194, 42.05713473317016, 42.597404951718396, 43.141702194811224, 43.6900349931913, 44.24241185063697, 44.798841244188324, 45.35933162437017, 45.92389141541209, 46.49252901546552, 47.065252796817916, 47.64207110610409, 48.22299226451468, 48.808024568002054, 49.3971762874833, 49.9904556690408, 50.587870934119984, 51.189430279724725, 51.79514187861014, 52.40501387947288, 53.0190544071392, 53.637271562750364, 54.259673423945976, 54.88626804504493, 55.517063457223934, 56.15206766869424, 56.79128866487574, 57.43473440856916, 58.08241284012621, 58.734331877617365, 59.39049941699807, 60.05092333227251, 60.715611475655585, 61.38457167773311, 62.057811747619894, 62.7353394731159, 63.417162620860914, 64.10328893648692, 64.79372614476921, 65.48848194977529, 66.18756403501224, 66.89098006357258, 67.59873767827808, 68.31084450182222, 69.02730813691093, 69.74813616640164, 70.47333615344107, 71.20291564160104, 71.93688215501312, 72.67524319850172, 73.41800625771542, 74.16517879925733, 74.9167682708136, 75.67278210128072, 76.43322770089146, 77.1981124613393, 77.96744375590167, 78.74122893956174, 79.51947534912904, 80.30219030335869, 81.08938110306934, 81.88105503125999, 82.67721935322541, 83.4778813166706, 84.28304815182372, 85.09272707154808, 85.90692527145302, 86.72564993000343, 87.54890820862819, 88.3767072518277, 89.2090541872801, 90.04595612594655, 90.88742016217518, 91.73345337380438, 92.58406282226491, 93.43925555268066, 94.29903859396902, 95.16341895893969, 96.03240364439274, 96.9059996312159, 97.78421388448044, 98.6670533535366, 99.55452497210776];/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class E { static from(t, r, n) { return new E(C.solveToInt(t, r, n)) } static fromInt(t) { return new E(t) } toInt() { return this.argb } get hue() { return this.internalHue } set hue(t) { this.setInternalState(C.solveToInt(t, this.internalChroma, this.internalTone)) } get chroma() { return this.internalChroma } set chroma(t) { this.setInternalState(C.solveToInt(this.internalHue, t, this.internalTone)) } get tone() { return this.internalTone } set tone(t) { this.setInternalState(C.solveToInt(this.internalHue, this.internalChroma, t)) } constructor(t) { this.argb = t; const r = z.fromInt(t); this.internalHue = r.hue, this.internalChroma = r.chroma, this.internalTone = Ct(t), this.argb = t } setInternalState(t) { const r = z.fromInt(t); this.internalHue = r.hue, this.internalChroma = r.chroma, this.internalTone = Ct(t), this.argb = t } inViewingConditions(t) { const n = z.fromInt(this.toInt()).xyzInViewingConditions(t), a = z.fromXyzInViewingConditions(n[0], n[1], n[2], v.make()); return E.from(a.hue, a.chroma, It(n[1])) } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class xt { static harmonize(t, r) { const n = E.fromInt(t), a = E.fromInt(r), o = Nt(n.hue, a.hue), s = Math.min(o * .5, 15), c = Dt(n.hue + s * jt(n.hue, a.hue)); return E.from(c, n.chroma, n.tone).toInt() } static hctHue(t, r, n) { const a = xt.cam16Ucs(t, r, n), o = z.fromInt(a), s = z.fromInt(t); return E.from(o.hue, s.chroma, Ct(t)).toInt() } static cam16Ucs(t, r, n) { const a = z.fromInt(t), o = z.fromInt(r), s = a.jstar, c = a.astar, u = a.bstar, h = o.jstar, l = o.astar, d = o.bstar, p = s + (h - s) * n, f = c + (l - c) * n, M = u + (d - u) * n; return z.fromUcs(p, f, M).toInt() } }/** + * @license + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class N { static ratioOfTones(t, r) { return t = ht(0, 100, t), r = ht(0, 100, r), N.ratioOfYs(Q(t), Q(r)) } static ratioOfYs(t, r) { const n = t > r ? t : r, a = n === r ? t : r; return (n + 5) / (a + 5) } static lighter(t, r) { if (t < 0 || t > 100) return -1; const n = Q(t), a = r * (n + 5) - 5, o = N.ratioOfYs(a, n), s = Math.abs(o - r); if (o < r && s > .04) return -1; const c = It(a) + .4; return c < 0 || c > 100 ? -1 : c } static darker(t, r) { if (t < 0 || t > 100) return -1; const n = Q(t), a = (n + 5) / r - 5, o = N.ratioOfYs(n, a), s = Math.abs(o - r); if (o < r && s > .04) return -1; const c = It(a) - .4; return c < 0 || c > 100 ? -1 : c } static lighterUnsafe(t, r) { const n = N.lighter(t, r); return n < 0 ? 100 : n } static darkerUnsafe(t, r) { const n = N.darker(t, r); return n < 0 ? 0 : n } }/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class At { static isDisliked(t) { const r = Math.round(t.hue) >= 90 && Math.round(t.hue) <= 111, n = Math.round(t.chroma) > 16, a = Math.round(t.tone) < 65; return r && n && a } static fixIfDisliked(t) { return At.isDisliked(t) ? E.from(t.hue, t.chroma, 70) : t } }/** + * @license + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class m { static fromPalette(t) { return new m(t.name ?? "", t.palette, t.tone, t.isBackground ?? !1, t.background, t.secondBackground, t.contrastCurve, t.toneDeltaPair) } constructor(t, r, n, a, o, s, c, u) { if (this.name = t, this.palette = r, this.tone = n, this.isBackground = a, this.background = o, this.secondBackground = s, this.contrastCurve = c, this.toneDeltaPair = u, this.hctCache = new Map, !o && s) throw new Error(`Color ${t} has secondBackgrounddefined, but background is not defined.`); if (!o && c) throw new Error(`Color ${t} has contrastCurvedefined, but background is not defined.`); if (o && !c) throw new Error(`Color ${t} has backgrounddefined, but contrastCurve is not defined.`) } getArgb(t) { return this.getHct(t).toInt() } getHct(t) { const r = this.hctCache.get(t); if (r != null) return r; const n = this.getTone(t), a = this.palette(t).getHct(n); return this.hctCache.size > 4 && this.hctCache.clear(), this.hctCache.set(t, a), a } getTone(t) { const r = t.contrastLevel < 0; if (this.toneDeltaPair) { const n = this.toneDeltaPair(t), a = n.roleA, o = n.roleB, s = n.delta, c = n.polarity, u = n.stayTogether, l = this.background(t).getTone(t), d = c === "nearer" || c === "lighter" && !t.isDark || c === "darker" && t.isDark, p = d ? a : o, f = d ? o : a, M = this.name === p.name, g = t.isDark ? 1 : -1, b = p.contrastCurve.getContrast(t.contrastLevel), w = f.contrastCurve.getContrast(t.contrastLevel), y = p.tone(t); let k = N.ratioOfTones(l, y) >= b ? y : m.foregroundTone(l, b); const A = f.tone(t); let D = N.ratioOfTones(l, A) >= w ? A : m.foregroundTone(l, w); return r && (k = m.foregroundTone(l, b), D = m.foregroundTone(l, w)), (D - k) * g >= s || (D = ht(0, 100, k + s * g), (D - k) * g >= s || (k = ht(0, 100, D - s * g))), 50 <= k && k < 60 ? g > 0 ? (k = 60, D = Math.max(D, k + s * g)) : (k = 49, D = Math.min(D, k + s * g)) : 50 <= D && D < 60 && (u ? g > 0 ? (k = 60, D = Math.max(D, k + s * g)) : (k = 49, D = Math.min(D, k + s * g)) : g > 0 ? D = 60 : D = 49), M ? k : D } else { let n = this.tone(t); if (this.background == null) return n; const a = this.background(t).getTone(t), o = this.contrastCurve.getContrast(t.contrastLevel); if (N.ratioOfTones(a, n) >= o || (n = m.foregroundTone(a, o)), r && (n = m.foregroundTone(a, o)), this.isBackground && 50 <= n && n < 60 && (N.ratioOfTones(49, a) >= o ? n = 49 : n = 60), this.secondBackground) { const [s, c] = [this.background, this.secondBackground], [u, h] = [s(t).getTone(t), c(t).getTone(t)], [l, d] = [Math.max(u, h), Math.min(u, h)]; if (N.ratioOfTones(l, n) >= o && N.ratioOfTones(d, n) >= o) return n; const p = N.lighter(l, o), f = N.darker(d, o), M = []; return p !== -1 && M.push(p), f !== -1 && M.push(f), m.tonePrefersLightForeground(u) || m.tonePrefersLightForeground(h) ? p < 0 ? 100 : p : M.length === 1 ? M[0] : f < 0 ? 0 : f } return n } } static foregroundTone(t, r) { const n = N.lighterUnsafe(t, r), a = N.darkerUnsafe(t, r), o = N.ratioOfTones(n, t), s = N.ratioOfTones(a, t); if (m.tonePrefersLightForeground(t)) { const u = Math.abs(o - s) < .1 && o < r && s < r; return o >= r || o >= s || u ? n : a } else return s >= r || s >= o ? a : n } static tonePrefersLightForeground(t) { return Math.round(t) < 60 } static toneAllowsLightForeground(t) { return Math.round(t) <= 49 } static enableLightForeground(t) { return m.tonePrefersLightForeground(t) && !m.toneAllowsLightForeground(t) ? 49 : t } }/** + * @license + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */var ot; (function (e) { e[e.MONOCHROME = 0] = "MONOCHROME", e[e.NEUTRAL = 1] = "NEUTRAL", e[e.TONAL_SPOT = 2] = "TONAL_SPOT", e[e.VIBRANT = 3] = "VIBRANT", e[e.EXPRESSIVE = 4] = "EXPRESSIVE", e[e.FIDELITY = 5] = "FIDELITY", e[e.CONTENT = 6] = "CONTENT", e[e.RAINBOW = 7] = "RAINBOW", e[e.FRUIT_SALAD = 8] = "FRUIT_SALAD" })(ot || (ot = {}));/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class x { constructor(t, r, n, a) { this.low = t, this.normal = r, this.medium = n, this.high = a } getContrast(t) { return t <= -1 ? this.low : t < 0 ? nt(this.low, this.normal, (t - -1) / 1) : t < .5 ? nt(this.normal, this.medium, (t - 0) / .5) : t < 1 ? nt(this.medium, this.high, (t - .5) / .5) : this.high } }/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class j { constructor(t, r, n, a, o) { this.roleA = t, this.roleB = r, this.delta = n, this.polarity = a, this.stayTogether = o } }/** + * @license + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */function et(e) { return e.variant === ot.FIDELITY || e.variant === ot.CONTENT } function O(e) { return e.variant === ot.MONOCHROME } function Qt(e, t, r, n) { let a = r, o = E.from(e, t, r); if (o.chroma < t) { let s = o.chroma; for (; o.chroma < t;) { a += n ? -1 : 1; const c = E.from(e, t, a); if (s > c.chroma || Math.abs(c.chroma - t) < .4) break; const u = Math.abs(c.chroma - t), h = Math.abs(o.chroma - t); u < h && (o = c), s = Math.max(s, c.chroma) } } return a } function Zt(e) { return v.make(void 0, void 0, e.isDark ? 30 : 80, void 0, void 0) } function Tt(e, t) { const r = e.inViewingConditions(Zt(t)); return m.tonePrefersLightForeground(e.tone) && !m.toneAllowsLightForeground(r.tone) ? m.enableLightForeground(e.tone) : m.enableLightForeground(r.tone) } class i { static highestSurface(t) { return t.isDark ? i.surfaceBright : i.surfaceDim } } i.contentAccentToneDelta = 15; i.primaryPaletteKeyColor = m.fromPalette({ name: "primary_palette_key_color", palette: e => e.primaryPalette, tone: e => e.primaryPalette.keyColor.tone }); i.secondaryPaletteKeyColor = m.fromPalette({ name: "secondary_palette_key_color", palette: e => e.secondaryPalette, tone: e => e.secondaryPalette.keyColor.tone }); i.tertiaryPaletteKeyColor = m.fromPalette({ name: "tertiary_palette_key_color", palette: e => e.tertiaryPalette, tone: e => e.tertiaryPalette.keyColor.tone }); i.neutralPaletteKeyColor = m.fromPalette({ name: "neutral_palette_key_color", palette: e => e.neutralPalette, tone: e => e.neutralPalette.keyColor.tone }); i.neutralVariantPaletteKeyColor = m.fromPalette({ name: "neutral_variant_palette_key_color", palette: e => e.neutralVariantPalette, tone: e => e.neutralVariantPalette.keyColor.tone }); i.background = m.fromPalette({ name: "background", palette: e => e.neutralPalette, tone: e => e.isDark ? 6 : 98, isBackground: !0 }); i.onBackground = m.fromPalette({ name: "on_background", palette: e => e.neutralPalette, tone: e => e.isDark ? 90 : 10, background: e => i.background, contrastCurve: new x(3, 3, 4.5, 7) }); i.surface = m.fromPalette({ name: "surface", palette: e => e.neutralPalette, tone: e => e.isDark ? 6 : 98, isBackground: !0 }); i.surfaceDim = m.fromPalette({ name: "surface_dim", palette: e => e.neutralPalette, tone: e => e.isDark ? 6 : 87, isBackground: !0 }); i.surfaceBright = m.fromPalette({ name: "surface_bright", palette: e => e.neutralPalette, tone: e => e.isDark ? 24 : 98, isBackground: !0 }); i.surfaceContainerLowest = m.fromPalette({ name: "surface_container_lowest", palette: e => e.neutralPalette, tone: e => e.isDark ? 4 : 100, isBackground: !0 }); i.surfaceContainerLow = m.fromPalette({ name: "surface_container_low", palette: e => e.neutralPalette, tone: e => e.isDark ? 10 : 96, isBackground: !0 }); i.surfaceContainer = m.fromPalette({ name: "surface_container", palette: e => e.neutralPalette, tone: e => e.isDark ? 12 : 94, isBackground: !0 }); i.surfaceContainerHigh = m.fromPalette({ name: "surface_container_high", palette: e => e.neutralPalette, tone: e => e.isDark ? 17 : 92, isBackground: !0 }); i.surfaceContainerHighest = m.fromPalette({ name: "surface_container_highest", palette: e => e.neutralPalette, tone: e => e.isDark ? 22 : 90, isBackground: !0 }); i.onSurface = m.fromPalette({ name: "on_surface", palette: e => e.neutralPalette, tone: e => e.isDark ? 90 : 10, background: e => i.highestSurface(e), contrastCurve: new x(4.5, 7, 11, 21) }); i.surfaceVariant = m.fromPalette({ name: "surface_variant", palette: e => e.neutralVariantPalette, tone: e => e.isDark ? 30 : 90, isBackground: !0 }); i.onSurfaceVariant = m.fromPalette({ name: "on_surface_variant", palette: e => e.neutralVariantPalette, tone: e => e.isDark ? 80 : 30, background: e => i.highestSurface(e), contrastCurve: new x(3, 4.5, 7, 11) }); i.inverseSurface = m.fromPalette({ name: "inverse_surface", palette: e => e.neutralPalette, tone: e => e.isDark ? 90 : 20 }); i.inverseOnSurface = m.fromPalette({ name: "inverse_on_surface", palette: e => e.neutralPalette, tone: e => e.isDark ? 20 : 95, background: e => i.inverseSurface, contrastCurve: new x(4.5, 7, 11, 21) }); i.outline = m.fromPalette({ name: "outline", palette: e => e.neutralVariantPalette, tone: e => e.isDark ? 60 : 50, background: e => i.highestSurface(e), contrastCurve: new x(1.5, 3, 4.5, 7) }); i.outlineVariant = m.fromPalette({ name: "outline_variant", palette: e => e.neutralVariantPalette, tone: e => e.isDark ? 30 : 80, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7) }); i.shadow = m.fromPalette({ name: "shadow", palette: e => e.neutralPalette, tone: e => 0 }); i.scrim = m.fromPalette({ name: "scrim", palette: e => e.neutralPalette, tone: e => 0 }); i.surfaceTint = m.fromPalette({ name: "surface_tint", palette: e => e.primaryPalette, tone: e => e.isDark ? 80 : 40, isBackground: !0 }); i.primary = m.fromPalette({ name: "primary", palette: e => e.primaryPalette, tone: e => O(e) ? e.isDark ? 100 : 0 : e.isDark ? 80 : 40, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(3, 4.5, 7, 11), toneDeltaPair: e => new j(i.primaryContainer, i.primary, 15, "nearer", !1) }); i.onPrimary = m.fromPalette({ name: "on_primary", palette: e => e.primaryPalette, tone: e => O(e) ? e.isDark ? 10 : 90 : e.isDark ? 20 : 100, background: e => i.primary, contrastCurve: new x(4.5, 7, 11, 21) }); i.primaryContainer = m.fromPalette({ name: "primary_container", palette: e => e.primaryPalette, tone: e => et(e) ? Tt(e.sourceColorHct, e) : O(e) ? e.isDark ? 85 : 25 : e.isDark ? 30 : 90, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.primaryContainer, i.primary, 15, "nearer", !1) }); i.onPrimaryContainer = m.fromPalette({ name: "on_primary_container", palette: e => e.primaryPalette, tone: e => et(e) ? m.foregroundTone(i.primaryContainer.tone(e), 4.5) : O(e) ? e.isDark ? 0 : 100 : e.isDark ? 90 : 10, background: e => i.primaryContainer, contrastCurve: new x(4.5, 7, 11, 21) }); i.inversePrimary = m.fromPalette({ name: "inverse_primary", palette: e => e.primaryPalette, tone: e => e.isDark ? 40 : 80, background: e => i.inverseSurface, contrastCurve: new x(3, 4.5, 7, 11) }); i.secondary = m.fromPalette({ name: "secondary", palette: e => e.secondaryPalette, tone: e => e.isDark ? 80 : 40, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(3, 4.5, 7, 11), toneDeltaPair: e => new j(i.secondaryContainer, i.secondary, 15, "nearer", !1) }); i.onSecondary = m.fromPalette({ name: "on_secondary", palette: e => e.secondaryPalette, tone: e => O(e) ? e.isDark ? 10 : 100 : e.isDark ? 20 : 100, background: e => i.secondary, contrastCurve: new x(4.5, 7, 11, 21) }); i.secondaryContainer = m.fromPalette({ name: "secondary_container", palette: e => e.secondaryPalette, tone: e => { const t = e.isDark ? 30 : 90; if (O(e)) return e.isDark ? 30 : 85; if (!et(e)) return t; let r = Qt(e.secondaryPalette.hue, e.secondaryPalette.chroma, t, !e.isDark); return r = Tt(e.secondaryPalette.getHct(r), e), r }, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.secondaryContainer, i.secondary, 15, "nearer", !1) }); i.onSecondaryContainer = m.fromPalette({ name: "on_secondary_container", palette: e => e.secondaryPalette, tone: e => et(e) ? m.foregroundTone(i.secondaryContainer.tone(e), 4.5) : e.isDark ? 90 : 10, background: e => i.secondaryContainer, contrastCurve: new x(4.5, 7, 11, 21) }); i.tertiary = m.fromPalette({ name: "tertiary", palette: e => e.tertiaryPalette, tone: e => O(e) ? e.isDark ? 90 : 25 : e.isDark ? 80 : 40, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(3, 4.5, 7, 11), toneDeltaPair: e => new j(i.tertiaryContainer, i.tertiary, 15, "nearer", !1) }); i.onTertiary = m.fromPalette({ name: "on_tertiary", palette: e => e.tertiaryPalette, tone: e => O(e) ? e.isDark ? 10 : 90 : e.isDark ? 20 : 100, background: e => i.tertiary, contrastCurve: new x(4.5, 7, 11, 21) }); i.tertiaryContainer = m.fromPalette({ name: "tertiary_container", palette: e => e.tertiaryPalette, tone: e => { if (O(e)) return e.isDark ? 60 : 49; if (!et(e)) return e.isDark ? 30 : 90; const t = Tt(e.tertiaryPalette.getHct(e.sourceColorHct.tone), e), r = e.tertiaryPalette.getHct(t); return At.fixIfDisliked(r).tone }, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.tertiaryContainer, i.tertiary, 15, "nearer", !1) }); i.onTertiaryContainer = m.fromPalette({ name: "on_tertiary_container", palette: e => e.tertiaryPalette, tone: e => O(e) ? e.isDark ? 0 : 100 : et(e) ? m.foregroundTone(i.tertiaryContainer.tone(e), 4.5) : e.isDark ? 90 : 10, background: e => i.tertiaryContainer, contrastCurve: new x(4.5, 7, 11, 21) }); i.error = m.fromPalette({ name: "error", palette: e => e.errorPalette, tone: e => e.isDark ? 80 : 40, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(3, 4.5, 7, 11), toneDeltaPair: e => new j(i.errorContainer, i.error, 15, "nearer", !1) }); i.onError = m.fromPalette({ name: "on_error", palette: e => e.errorPalette, tone: e => e.isDark ? 20 : 100, background: e => i.error, contrastCurve: new x(4.5, 7, 11, 21) }); i.errorContainer = m.fromPalette({ name: "error_container", palette: e => e.errorPalette, tone: e => e.isDark ? 30 : 90, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.errorContainer, i.error, 15, "nearer", !1) }); i.onErrorContainer = m.fromPalette({ name: "on_error_container", palette: e => e.errorPalette, tone: e => e.isDark ? 90 : 10, background: e => i.errorContainer, contrastCurve: new x(4.5, 7, 11, 21) }); i.primaryFixed = m.fromPalette({ name: "primary_fixed", palette: e => e.primaryPalette, tone: e => O(e) ? 40 : 90, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.primaryFixed, i.primaryFixedDim, 10, "lighter", !0) }); i.primaryFixedDim = m.fromPalette({ name: "primary_fixed_dim", palette: e => e.primaryPalette, tone: e => O(e) ? 30 : 80, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.primaryFixed, i.primaryFixedDim, 10, "lighter", !0) }); i.onPrimaryFixed = m.fromPalette({ name: "on_primary_fixed", palette: e => e.primaryPalette, tone: e => O(e) ? 100 : 10, background: e => i.primaryFixedDim, secondBackground: e => i.primaryFixed, contrastCurve: new x(4.5, 7, 11, 21) }); i.onPrimaryFixedVariant = m.fromPalette({ name: "on_primary_fixed_variant", palette: e => e.primaryPalette, tone: e => O(e) ? 90 : 30, background: e => i.primaryFixedDim, secondBackground: e => i.primaryFixed, contrastCurve: new x(3, 4.5, 7, 11) }); i.secondaryFixed = m.fromPalette({ name: "secondary_fixed", palette: e => e.secondaryPalette, tone: e => O(e) ? 80 : 90, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.secondaryFixed, i.secondaryFixedDim, 10, "lighter", !0) }); i.secondaryFixedDim = m.fromPalette({ name: "secondary_fixed_dim", palette: e => e.secondaryPalette, tone: e => O(e) ? 70 : 80, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.secondaryFixed, i.secondaryFixedDim, 10, "lighter", !0) }); i.onSecondaryFixed = m.fromPalette({ name: "on_secondary_fixed", palette: e => e.secondaryPalette, tone: e => 10, background: e => i.secondaryFixedDim, secondBackground: e => i.secondaryFixed, contrastCurve: new x(4.5, 7, 11, 21) }); i.onSecondaryFixedVariant = m.fromPalette({ name: "on_secondary_fixed_variant", palette: e => e.secondaryPalette, tone: e => O(e) ? 25 : 30, background: e => i.secondaryFixedDim, secondBackground: e => i.secondaryFixed, contrastCurve: new x(3, 4.5, 7, 11) }); i.tertiaryFixed = m.fromPalette({ name: "tertiary_fixed", palette: e => e.tertiaryPalette, tone: e => O(e) ? 40 : 90, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.tertiaryFixed, i.tertiaryFixedDim, 10, "lighter", !0) }); i.tertiaryFixedDim = m.fromPalette({ name: "tertiary_fixed_dim", palette: e => e.tertiaryPalette, tone: e => O(e) ? 30 : 80, isBackground: !0, background: e => i.highestSurface(e), contrastCurve: new x(1, 1, 3, 7), toneDeltaPair: e => new j(i.tertiaryFixed, i.tertiaryFixedDim, 10, "lighter", !0) }); i.onTertiaryFixed = m.fromPalette({ name: "on_tertiary_fixed", palette: e => e.tertiaryPalette, tone: e => O(e) ? 100 : 10, background: e => i.tertiaryFixedDim, secondBackground: e => i.tertiaryFixed, contrastCurve: new x(4.5, 7, 11, 21) }); i.onTertiaryFixedVariant = m.fromPalette({ name: "on_tertiary_fixed_variant", palette: e => e.tertiaryPalette, tone: e => O(e) ? 90 : 30, background: e => i.tertiaryFixedDim, secondBackground: e => i.tertiaryFixed, contrastCurve: new x(3, 4.5, 7, 11) });/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class G { static fromInt(t) { const r = E.fromInt(t); return G.fromHct(r) } static fromHct(t) { return new G(t.hue, t.chroma, t) } static fromHueAndChroma(t, r) { return new G(t, r, G.createKeyColor(t, r)) } constructor(t, r, n) { this.hue = t, this.chroma = r, this.keyColor = n, this.cache = new Map } static createKeyColor(t, r) { let a = E.from(t, r, 50), o = Math.abs(a.chroma - r); for (let s = 1; s < 50; s += 1) { if (Math.round(r) === Math.round(a.chroma)) return a; const c = E.from(t, r, 50 + s), u = Math.abs(c.chroma - r); u < o && (o = u, a = c); const h = E.from(t, r, 50 - s), l = Math.abs(h.chroma - r); l < o && (o = l, a = h) } return a } tone(t) { let r = this.cache.get(t); return r === void 0 && (r = E.from(this.hue, this.chroma, t).toInt(), this.cache.set(t, r)), r } getHct(t) { return E.fromInt(this.tone(t)) } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class S { static of(t) { return new S(t, !1) } static contentOf(t) { return new S(t, !0) } static fromColors(t) { return S.createPaletteFromColors(!1, t) } static contentFromColors(t) { return S.createPaletteFromColors(!0, t) } static createPaletteFromColors(t, r) { const n = new S(r.primary, t); if (r.secondary) { const a = new S(r.secondary, t); n.a2 = a.a1 } if (r.tertiary) { const a = new S(r.tertiary, t); n.a3 = a.a1 } if (r.error) { const a = new S(r.error, t); n.error = a.a1 } if (r.neutral) { const a = new S(r.neutral, t); n.n1 = a.n1 } if (r.neutralVariant) { const a = new S(r.neutralVariant, t); n.n2 = a.n2 } return n } constructor(t, r) { const n = E.fromInt(t), a = n.hue, o = n.chroma; r ? (this.a1 = G.fromHueAndChroma(a, o), this.a2 = G.fromHueAndChroma(a, o / 3), this.a3 = G.fromHueAndChroma(a + 60, o / 2), this.n1 = G.fromHueAndChroma(a, Math.min(o / 12, 4)), this.n2 = G.fromHueAndChroma(a, Math.min(o / 6, 8))) : (this.a1 = G.fromHueAndChroma(a, Math.max(48, o)), this.a2 = G.fromHueAndChroma(a, 16), this.a3 = G.fromHueAndChroma(a + 60, 24), this.n1 = G.fromHueAndChroma(a, 4), this.n2 = G.fromHueAndChroma(a, 8)), this.error = G.fromHueAndChroma(25, 84) } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class te { fromInt(t) { return Xt(t) } toInt(t) { return Jt(t[0], t[1], t[2]) } distance(t, r) { const n = t[0] - r[0], a = t[1] - r[1], o = t[2] - r[2]; return n * n + a * a + o * o } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */const ee = 10, re = 3; class ne { static quantize(t, r, n) { const a = new Map, o = new Array, s = new Array, c = new te; let u = 0; for (let y = 0; y < t.length; y++) { const k = t[y], A = a.get(k); A === void 0 ? (u++, o.push(c.fromInt(k)), s.push(k), a.set(k, 1)) : a.set(k, A + 1) } const h = new Array; for (let y = 0; y < u; y++) { const k = s[y], A = a.get(k); A !== void 0 && (h[y] = A) } let l = Math.min(n, u); r.length > 0 && (l = Math.min(l, r.length)); const d = new Array; for (let y = 0; y < r.length; y++)d.push(c.fromInt(r[y])); const p = l - d.length; if (r.length === 0 && p > 0) for (let y = 0; y < p; y++) { const k = Math.random() * 100, A = Math.random() * (100 - -100 + 1) + -100, D = Math.random() * (100 - -100 + 1) + -100; d.push(new Array(k, A, D)) } const f = new Array; for (let y = 0; y < u; y++)f.push(Math.floor(Math.random() * l)); const M = new Array; for (let y = 0; y < l; y++) { M.push(new Array); for (let k = 0; k < l; k++)M[y].push(0) } const g = new Array; for (let y = 0; y < l; y++) { g.push(new Array); for (let k = 0; k < l; k++)g[y].push(new ae) } const b = new Array; for (let y = 0; y < l; y++)b.push(0); for (let y = 0; y < ee; y++) { for (let P = 0; P < l; P++) { for (let I = P + 1; I < l; I++) { const B = c.distance(d[P], d[I]); g[I][P].distance = B, g[I][P].index = P, g[P][I].distance = B, g[P][I].index = I } g[P].sort(); for (let I = 0; I < l; I++)M[P][I] = g[P][I].index } let k = 0; for (let P = 0; P < u; P++) { const I = o[P], B = f[P], T = d[B], V = c.distance(I, T); let Y = V, U = -1; for (let L = 0; L < l; L++) { if (g[B][L].distance >= 4 * V) continue; const Z = c.distance(I, d[L]); Z < Y && (Y = Z, U = L) } U !== -1 && Math.abs(Math.sqrt(Y) - Math.sqrt(V)) > re && (k++, f[P] = U) } if (k === 0 && y !== 0) break; const A = new Array(l).fill(0), D = new Array(l).fill(0), R = new Array(l).fill(0); for (let P = 0; P < l; P++)b[P] = 0; for (let P = 0; P < u; P++) { const I = f[P], B = o[P], T = h[P]; b[I] += T, A[I] += B[0] * T, D[I] += B[1] * T, R[I] += B[2] * T } for (let P = 0; P < l; P++) { const I = b[P]; if (I === 0) { d[P] = [0, 0, 0]; continue } const B = A[P] / I, T = D[P] / I, V = R[P] / I; d[P] = [B, T, V] } } const w = new Map; for (let y = 0; y < l; y++) { const k = b[y]; if (k === 0) continue; const A = c.toInt(d[y]); w.has(A) || w.set(A, k) } return w } } class ae { constructor() { this.distance = -1, this.index = -1 } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class oe { static quantize(t) { const r = new Map; for (let n = 0; n < t.length; n++) { const a = t[n]; Wt(a) < 255 || r.set(a, (r.get(a) ?? 0) + 1) } return r } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */const lt = 5, W = 33, rt = 35937, _ = { RED: "red", GREEN: "green", BLUE: "blue" }; class se { constructor(t = [], r = [], n = [], a = [], o = [], s = []) { this.weights = t, this.momentsR = r, this.momentsG = n, this.momentsB = a, this.moments = o, this.cubes = s } quantize(t, r) { this.constructHistogram(t), this.computeMoments(); const n = this.createBoxes(r); return this.createResult(n.resultCount) } constructHistogram(t) { this.weights = Array.from({ length: rt }).fill(0), this.momentsR = Array.from({ length: rt }).fill(0), this.momentsG = Array.from({ length: rt }).fill(0), this.momentsB = Array.from({ length: rt }).fill(0), this.moments = Array.from({ length: rt }).fill(0); const r = oe.quantize(t); for (const [n, a] of r.entries()) { const o = dt(n), s = mt(n), c = gt(n), u = 8 - lt, h = (o >> u) + 1, l = (s >> u) + 1, d = (c >> u) + 1, p = this.getIndex(h, l, d); this.weights[p] = (this.weights[p] ?? 0) + a, this.momentsR[p] += a * o, this.momentsG[p] += a * s, this.momentsB[p] += a * c, this.moments[p] += a * (o * o + s * s + c * c) } } computeMoments() { for (let t = 1; t < W; t++) { const r = Array.from({ length: W }).fill(0), n = Array.from({ length: W }).fill(0), a = Array.from({ length: W }).fill(0), o = Array.from({ length: W }).fill(0), s = Array.from({ length: W }).fill(0); for (let c = 1; c < W; c++) { let u = 0, h = 0, l = 0, d = 0, p = 0; for (let f = 1; f < W; f++) { const M = this.getIndex(t, c, f); u += this.weights[M], h += this.momentsR[M], l += this.momentsG[M], d += this.momentsB[M], p += this.moments[M], r[f] += u, n[f] += h, a[f] += l, o[f] += d, s[f] += p; const g = this.getIndex(t - 1, c, f); this.weights[M] = this.weights[g] + r[f], this.momentsR[M] = this.momentsR[g] + n[f], this.momentsG[M] = this.momentsG[g] + a[f], this.momentsB[M] = this.momentsB[g] + o[f], this.moments[M] = this.moments[g] + s[f] } } } } createBoxes(t) { this.cubes = Array.from({ length: t }).fill(0).map(() => new ie); const r = Array.from({ length: t }).fill(0); this.cubes[0].r0 = 0, this.cubes[0].g0 = 0, this.cubes[0].b0 = 0, this.cubes[0].r1 = W - 1, this.cubes[0].g1 = W - 1, this.cubes[0].b1 = W - 1; let n = t, a = 0; for (let o = 1; o < t; o++) { this.cut(this.cubes[a], this.cubes[o]) ? (r[a] = this.cubes[a].vol > 1 ? this.variance(this.cubes[a]) : 0, r[o] = this.cubes[o].vol > 1 ? this.variance(this.cubes[o]) : 0) : (r[a] = 0, o--), a = 0; let s = r[0]; for (let c = 1; c <= o; c++)r[c] > s && (s = r[c], a = c); if (s <= 0) { n = o + 1; break } } return new ce(t, n) } createResult(t) { const r = []; for (let n = 0; n < t; ++n) { const a = this.cubes[n], o = this.volume(a, this.weights); if (o > 0) { const s = Math.round(this.volume(a, this.momentsR) / o), c = Math.round(this.volume(a, this.momentsG) / o), u = Math.round(this.volume(a, this.momentsB) / o), h = 255 << 24 | (s & 255) << 16 | (c & 255) << 8 | u & 255; r.push(h) } } return r } variance(t) { const r = this.volume(t, this.momentsR), n = this.volume(t, this.momentsG), a = this.volume(t, this.momentsB), o = this.moments[this.getIndex(t.r1, t.g1, t.b1)] - this.moments[this.getIndex(t.r1, t.g1, t.b0)] - this.moments[this.getIndex(t.r1, t.g0, t.b1)] + this.moments[this.getIndex(t.r1, t.g0, t.b0)] - this.moments[this.getIndex(t.r0, t.g1, t.b1)] + this.moments[this.getIndex(t.r0, t.g1, t.b0)] + this.moments[this.getIndex(t.r0, t.g0, t.b1)] - this.moments[this.getIndex(t.r0, t.g0, t.b0)], s = r * r + n * n + a * a, c = this.volume(t, this.weights); return o - s / c } cut(t, r) { const n = this.volume(t, this.momentsR), a = this.volume(t, this.momentsG), o = this.volume(t, this.momentsB), s = this.volume(t, this.weights), c = this.maximize(t, _.RED, t.r0 + 1, t.r1, n, a, o, s), u = this.maximize(t, _.GREEN, t.g0 + 1, t.g1, n, a, o, s), h = this.maximize(t, _.BLUE, t.b0 + 1, t.b1, n, a, o, s); let l; const d = c.maximum, p = u.maximum, f = h.maximum; if (d >= p && d >= f) { if (c.cutLocation < 0) return !1; l = _.RED } else p >= d && p >= f ? l = _.GREEN : l = _.BLUE; switch (r.r1 = t.r1, r.g1 = t.g1, r.b1 = t.b1, l) { case _.RED: t.r1 = c.cutLocation, r.r0 = t.r1, r.g0 = t.g0, r.b0 = t.b0; break; case _.GREEN: t.g1 = u.cutLocation, r.r0 = t.r0, r.g0 = t.g1, r.b0 = t.b0; break; case _.BLUE: t.b1 = h.cutLocation, r.r0 = t.r0, r.g0 = t.g0, r.b0 = t.b1; break; default: throw new Error("unexpected direction " + l) }return t.vol = (t.r1 - t.r0) * (t.g1 - t.g0) * (t.b1 - t.b0), r.vol = (r.r1 - r.r0) * (r.g1 - r.g0) * (r.b1 - r.b0), !0 } maximize(t, r, n, a, o, s, c, u) { const h = this.bottom(t, r, this.momentsR), l = this.bottom(t, r, this.momentsG), d = this.bottom(t, r, this.momentsB), p = this.bottom(t, r, this.weights); let f = 0, M = -1, g = 0, b = 0, w = 0, y = 0; for (let k = n; k < a; k++) { if (g = h + this.top(t, r, k, this.momentsR), b = l + this.top(t, r, k, this.momentsG), w = d + this.top(t, r, k, this.momentsB), y = p + this.top(t, r, k, this.weights), y === 0) continue; let A = (g * g + b * b + w * w) * 1, D = y * 1, R = A / D; g = o - g, b = s - b, w = c - w, y = u - y, y !== 0 && (A = (g * g + b * b + w * w) * 1, D = y * 1, R += A / D, R > f && (f = R, M = k)) } return new le(M, f) } volume(t, r) { return r[this.getIndex(t.r1, t.g1, t.b1)] - r[this.getIndex(t.r1, t.g1, t.b0)] - r[this.getIndex(t.r1, t.g0, t.b1)] + r[this.getIndex(t.r1, t.g0, t.b0)] - r[this.getIndex(t.r0, t.g1, t.b1)] + r[this.getIndex(t.r0, t.g1, t.b0)] + r[this.getIndex(t.r0, t.g0, t.b1)] - r[this.getIndex(t.r0, t.g0, t.b0)] } bottom(t, r, n) { switch (r) { case _.RED: return -n[this.getIndex(t.r0, t.g1, t.b1)] + n[this.getIndex(t.r0, t.g1, t.b0)] + n[this.getIndex(t.r0, t.g0, t.b1)] - n[this.getIndex(t.r0, t.g0, t.b0)]; case _.GREEN: return -n[this.getIndex(t.r1, t.g0, t.b1)] + n[this.getIndex(t.r1, t.g0, t.b0)] + n[this.getIndex(t.r0, t.g0, t.b1)] - n[this.getIndex(t.r0, t.g0, t.b0)]; case _.BLUE: return -n[this.getIndex(t.r1, t.g1, t.b0)] + n[this.getIndex(t.r1, t.g0, t.b0)] + n[this.getIndex(t.r0, t.g1, t.b0)] - n[this.getIndex(t.r0, t.g0, t.b0)]; default: throw new Error("unexpected direction $direction") } } top(t, r, n, a) { switch (r) { case _.RED: return a[this.getIndex(n, t.g1, t.b1)] - a[this.getIndex(n, t.g1, t.b0)] - a[this.getIndex(n, t.g0, t.b1)] + a[this.getIndex(n, t.g0, t.b0)]; case _.GREEN: return a[this.getIndex(t.r1, n, t.b1)] - a[this.getIndex(t.r1, n, t.b0)] - a[this.getIndex(t.r0, n, t.b1)] + a[this.getIndex(t.r0, n, t.b0)]; case _.BLUE: return a[this.getIndex(t.r1, t.g1, n)] - a[this.getIndex(t.r1, t.g0, n)] - a[this.getIndex(t.r0, t.g1, n)] + a[this.getIndex(t.r0, t.g0, n)]; default: throw new Error("unexpected direction $direction") } } getIndex(t, r, n) { return (t << lt * 2) + (t << lt + 1) + t + (r << lt) + r + n } } class ie { constructor(t = 0, r = 0, n = 0, a = 0, o = 0, s = 0, c = 0) { this.r0 = t, this.r1 = r, this.g0 = n, this.g1 = a, this.b0 = o, this.b1 = s, this.vol = c } } class ce { constructor(t, r) { this.requestedCount = t, this.resultCount = r } } class le { constructor(t, r) { this.cutLocation = t, this.maximum = r } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class ue { static quantize(t, r) { const a = new se().quantize(t, r); return ne.quantize(t, a, r) } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class X { get primary() { return this.props.primary } get onPrimary() { return this.props.onPrimary } get primaryContainer() { return this.props.primaryContainer } get onPrimaryContainer() { return this.props.onPrimaryContainer } get secondary() { return this.props.secondary } get onSecondary() { return this.props.onSecondary } get secondaryContainer() { return this.props.secondaryContainer } get onSecondaryContainer() { return this.props.onSecondaryContainer } get tertiary() { return this.props.tertiary } get onTertiary() { return this.props.onTertiary } get tertiaryContainer() { return this.props.tertiaryContainer } get onTertiaryContainer() { return this.props.onTertiaryContainer } get error() { return this.props.error } get onError() { return this.props.onError } get errorContainer() { return this.props.errorContainer } get onErrorContainer() { return this.props.onErrorContainer } get background() { return this.props.background } get onBackground() { return this.props.onBackground } get surface() { return this.props.surface } get onSurface() { return this.props.onSurface } get surfaceVariant() { return this.props.surfaceVariant } get onSurfaceVariant() { return this.props.onSurfaceVariant } get outline() { return this.props.outline } get outlineVariant() { return this.props.outlineVariant } get shadow() { return this.props.shadow } get scrim() { return this.props.scrim } get inverseSurface() { return this.props.inverseSurface } get inverseOnSurface() { return this.props.inverseOnSurface } get inversePrimary() { return this.props.inversePrimary } static light(t) { return X.lightFromCorePalette(S.of(t)) } static dark(t) { return X.darkFromCorePalette(S.of(t)) } static lightContent(t) { return X.lightFromCorePalette(S.contentOf(t)) } static darkContent(t) { return X.darkFromCorePalette(S.contentOf(t)) } static lightFromCorePalette(t) { return new X({ primary: t.a1.tone(40), onPrimary: t.a1.tone(100), primaryContainer: t.a1.tone(90), onPrimaryContainer: t.a1.tone(10), secondary: t.a2.tone(40), onSecondary: t.a2.tone(100), secondaryContainer: t.a2.tone(90), onSecondaryContainer: t.a2.tone(10), tertiary: t.a3.tone(40), onTertiary: t.a3.tone(100), tertiaryContainer: t.a3.tone(90), onTertiaryContainer: t.a3.tone(10), error: t.error.tone(40), onError: t.error.tone(100), errorContainer: t.error.tone(90), onErrorContainer: t.error.tone(10), background: t.n1.tone(99), onBackground: t.n1.tone(10), surface: t.n1.tone(99), onSurface: t.n1.tone(10), surfaceVariant: t.n2.tone(90), onSurfaceVariant: t.n2.tone(30), outline: t.n2.tone(50), outlineVariant: t.n2.tone(80), shadow: t.n1.tone(0), scrim: t.n1.tone(0), inverseSurface: t.n1.tone(20), inverseOnSurface: t.n1.tone(95), inversePrimary: t.a1.tone(80) }) } static darkFromCorePalette(t) { return new X({ primary: t.a1.tone(80), onPrimary: t.a1.tone(20), primaryContainer: t.a1.tone(30), onPrimaryContainer: t.a1.tone(90), secondary: t.a2.tone(80), onSecondary: t.a2.tone(20), secondaryContainer: t.a2.tone(30), onSecondaryContainer: t.a2.tone(90), tertiary: t.a3.tone(80), onTertiary: t.a3.tone(20), tertiaryContainer: t.a3.tone(30), onTertiaryContainer: t.a3.tone(90), error: t.error.tone(80), onError: t.error.tone(20), errorContainer: t.error.tone(30), onErrorContainer: t.error.tone(80), background: t.n1.tone(10), onBackground: t.n1.tone(90), surface: t.n1.tone(10), onSurface: t.n1.tone(90), surfaceVariant: t.n2.tone(30), onSurfaceVariant: t.n2.tone(80), outline: t.n2.tone(60), outlineVariant: t.n2.tone(30), shadow: t.n1.tone(0), scrim: t.n1.tone(0), inverseSurface: t.n1.tone(90), inverseOnSurface: t.n1.tone(20), inversePrimary: t.a1.tone(40) }) } constructor(t) { this.props = t } toJSON() { return { ...this.props } } }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */const he = { desired: 4, fallbackColorARGB: 4282549748, filter: !0 }; function fe(e, t) { return e.score > t.score ? -1 : e.score < t.score ? 1 : 0 } class H { constructor() { } static score(t, r) { const { desired: n, fallbackColorARGB: a, filter: o } = { ...he, ...r }, s = [], c = new Array(360).fill(0); let u = 0; for (const [f, M] of t.entries()) { const g = E.fromInt(f); s.push(g); const b = Math.floor(g.hue); c[b] += M, u += M } const h = new Array(360).fill(0); for (let f = 0; f < 360; f++) { const M = c[f] / u; for (let g = f - 14; g < f + 16; g++) { const b = Ot(g); h[b] += M } } const l = new Array; for (const f of s) { const M = Ot(Math.round(f.hue)), g = h[M]; if (o && (f.chroma < H.CUTOFF_CHROMA || g <= H.CUTOFF_EXCITED_PROPORTION)) continue; const b = g * 100 * H.WEIGHT_PROPORTION, w = f.chroma < H.TARGET_CHROMA ? H.WEIGHT_CHROMA_BELOW : H.WEIGHT_CHROMA_ABOVE, y = (f.chroma - H.TARGET_CHROMA) * w, k = b + y; l.push({ hct: f, score: k }) } l.sort(fe); const d = []; for (let f = 90; f >= 15; f--) { d.length = 0; for (const { hct: M } of l) if (d.find(b => Nt(M.hue, b.hue) < f) || d.push(M), d.length >= n) break; if (d.length >= n) break } const p = []; d.length === 0 && p.push(a); for (const f of d) p.push(f.toInt()); return p } } H.TARGET_CHROMA = 48; H.WEIGHT_PROPORTION = .7; H.WEIGHT_CHROMA_ABOVE = .3; H.WEIGHT_CHROMA_BELOW = .1; H.CUTOFF_CHROMA = 5; H.CUTOFF_EXCITED_PROPORTION = .01;/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */function F(e) { const t = dt(e), r = mt(e), n = gt(e), a = [t.toString(16), r.toString(16), n.toString(16)]; for (const [o, s] of a.entries()) s.length === 1 && (a[o] = "0" + s); return "#" + a.join("") } function de(e) { e = e.replace("#", ""); const t = e.length === 3, r = e.length === 6, n = e.length === 8; if (!t && !r && !n) throw new Error("unexpected hex " + e); let a = 0, o = 0, s = 0; return t ? (a = J(e.slice(0, 1).repeat(2)), o = J(e.slice(1, 2).repeat(2)), s = J(e.slice(2, 3).repeat(2))) : r ? (a = J(e.slice(0, 2)), o = J(e.slice(2, 4)), s = J(e.slice(4, 6))) : n && (a = J(e.slice(2, 4)), o = J(e.slice(4, 6)), s = J(e.slice(6, 8))), (255 << 24 | (a & 255) << 16 | (o & 255) << 8 | s & 255) >>> 0 } function J(e) { return parseInt(e, 16) }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */async function me(e) { const t = await new Promise((s, c) => { const u = document.createElement("canvas"), h = u.getContext("2d"); if (!h) { c(new Error("Could not get canvas context")); return } const l = () => { u.width = e.width, u.height = e.height, h.drawImage(e, 0, 0); let d = [0, 0, e.width, e.height]; const p = e.dataset.area; p && /^\d+(\s*,\s*\d+){3}$/.test(p) && (d = p.split(/\s*,\s*/).map(w => parseInt(w, 10))); const [f, M, g, b] = d; s(h.getImageData(f, M, g, b).data) }; e.complete ? l() : e.onload = l }), r = []; for (let s = 0; s < t.length; s += 4) { const c = t[s], u = t[s + 1], h = t[s + 2]; if (t[s + 3] < 255) continue; const d = ft(c, u, h); r.push(d) } const n = ue.quantize(r, 128); return H.score(n)[0] }/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */function Gt(e, t = []) { const r = S.of(e); return { source: e, schemes: { light: X.light(e), dark: X.dark(e) }, palettes: { primary: r.a1, secondary: r.a2, tertiary: r.a3, neutral: r.n1, neutralVariant: r.n2, error: r.error }, customColors: t.map(n => ge(e, n)) } } async function Lt(e, t = []) { const r = await me(e); return Gt(r, t) } function ge(e, t) { let r = t.value; const n = r, a = e; t.blend && (r = xt.harmonize(n, a)); const s = S.of(r).a1; return { color: t, value: r, light: { color: s.tone(40), onColor: s.tone(100), colorContainer: s.tone(90), onColorContainer: s.tone(10) }, dark: { color: s.tone(80), onColor: s.tone(20), colorContainer: s.tone(30), onColorContainer: s.tone(90) } } } function Pt(e) { let t = JSON.parse(JSON.stringify(e.schemes)); for (let r in t) for (let n in t[r]) t[r][n] = F(t[r][n]); return t.dark.surfaceDim = F(e.palettes.neutral.tone(6)), t.dark.surface = F(e.palettes.neutral.tone(6)), t.dark.surfaceBright = F(e.palettes.neutral.tone(24)), t.dark.surfaceContainerLowest = F(e.palettes.neutral.tone(4)), t.dark.surfaceContainerLow = F(e.palettes.neutral.tone(10)), t.dark.surfaceContainer = F(e.palettes.neutral.tone(12)), t.dark.surfaceContainerHigh = F(e.palettes.neutral.tone(17)), t.dark.surfaceContainerHighest = F(e.palettes.neutral.tone(22)), t.dark.onSurface = F(e.palettes.neutral.tone(90)), t.dark.onSurfaceVariant = F(e.palettes.neutralVariant.tone(80)), t.dark.outline = F(e.palettes.neutralVariant.tone(60)), t.dark.outlineVariant = F(e.palettes.neutralVariant.tone(30)), t.light.surfaceDim = F(e.palettes.neutral.tone(87)), t.light.surface = F(e.palettes.neutral.tone(98)), t.light.surfaceBright = F(e.palettes.neutral.tone(98)), t.light.surfaceContainerLowest = F(e.palettes.neutral.tone(100)), t.light.surfaceContainerLow = F(e.palettes.neutral.tone(96)), t.light.surfaceContainer = F(e.palettes.neutral.tone(94)), t.light.surfaceContainerHigh = F(e.palettes.neutral.tone(92)), t.light.surfaceContainerHighest = F(e.palettes.neutral.tone(90)), t.light.onSurface = F(e.palettes.neutral.tone(10)), t.light.onSurfaceVariant = F(e.palettes.neutralVariant.tone(30)), t.light.outline = F(e.palettes.neutralVariant.tone(50)), t.light.outlineVariant = F(e.palettes.neutralVariant.tone(80)), t } async function pe(e) { const t = e, r = { light: {}, dark: {} }; try { if (typeof t == "string" && /^\#[0-9a-f]+$/i.test(t)) { let s = Gt(de(t)); return Pt(s) } if (t.src) { let s = await Lt(t); return Pt(s) } let n = new Blob; if (typeof t == "string" && (n = await fetch(t).then(s => s.blob())), t.size && (n = t), t.files && t.files[0] && (n = t.files[0]), t.target && t.target.files && t.target.files[0] && (n = t.target.files[0]), !n.size) return r; let a = new Image(64); a.src = URL.createObjectURL(n); let o = await Lt(a); return Pt(o) } catch { return r } } globalThis.materialDynamicColors = pe; + return globalThis.materialDynamicColors; +})(); \ No newline at end of file diff --git a/assets/material-symbols-outlined.woff2 b/assets/material-symbols-outlined.woff2 new file mode 100644 index 0000000..2764906 Binary files /dev/null and b/assets/material-symbols-outlined.woff2 differ diff --git a/assets/material-symbols-rounded.woff2 b/assets/material-symbols-rounded.woff2 new file mode 100644 index 0000000..f4505dc Binary files /dev/null and b/assets/material-symbols-rounded.woff2 differ diff --git a/assets/material-symbols-sharp.woff2 b/assets/material-symbols-sharp.woff2 new file mode 100644 index 0000000..cc5482e Binary files /dev/null and b/assets/material-symbols-sharp.woff2 differ diff --git a/assets/pico-1.5.9/.github/CONTRIBUTING.md b/pico-1.5.9/.github/CONTRIBUTING.md similarity index 100% rename from assets/pico-1.5.9/.github/CONTRIBUTING.md rename to pico-1.5.9/.github/CONTRIBUTING.md diff --git a/assets/pico-1.5.9/.github/ISSUE_TEMPLATE/bug_report.md b/pico-1.5.9/.github/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from assets/pico-1.5.9/.github/ISSUE_TEMPLATE/bug_report.md rename to pico-1.5.9/.github/ISSUE_TEMPLATE/bug_report.md diff --git a/assets/pico-1.5.9/.github/ISSUE_TEMPLATE/config.yml b/pico-1.5.9/.github/ISSUE_TEMPLATE/config.yml similarity index 100% rename from assets/pico-1.5.9/.github/ISSUE_TEMPLATE/config.yml rename to pico-1.5.9/.github/ISSUE_TEMPLATE/config.yml diff --git a/assets/pico-1.5.9/.github/examples.jpg b/pico-1.5.9/.github/examples.jpg similarity index 100% rename from assets/pico-1.5.9/.github/examples.jpg rename to pico-1.5.9/.github/examples.jpg diff --git a/assets/pico-1.5.9/.github/logo.svg b/pico-1.5.9/.github/logo.svg similarity index 100% rename from assets/pico-1.5.9/.github/logo.svg rename to pico-1.5.9/.github/logo.svg diff --git a/assets/pico-1.5.9/.gitignore b/pico-1.5.9/.gitignore similarity index 100% rename from assets/pico-1.5.9/.gitignore rename to pico-1.5.9/.gitignore diff --git a/assets/pico-1.5.9/LICENSE.md b/pico-1.5.9/LICENSE.md similarity index 100% rename from assets/pico-1.5.9/LICENSE.md rename to pico-1.5.9/LICENSE.md diff --git a/assets/pico-1.5.9/README.md b/pico-1.5.9/README.md similarity index 100% rename from assets/pico-1.5.9/README.md rename to pico-1.5.9/README.md diff --git a/assets/pico-1.5.9/composer.json b/pico-1.5.9/composer.json similarity index 100% rename from assets/pico-1.5.9/composer.json rename to pico-1.5.9/composer.json diff --git a/assets/pico-1.5.9/css/pico.classless.css b/pico-1.5.9/css/pico.classless.css similarity index 100% rename from assets/pico-1.5.9/css/pico.classless.css rename to pico-1.5.9/css/pico.classless.css diff --git a/assets/pico-1.5.9/css/pico.classless.css.map b/pico-1.5.9/css/pico.classless.css.map similarity index 100% rename from assets/pico-1.5.9/css/pico.classless.css.map rename to pico-1.5.9/css/pico.classless.css.map diff --git a/assets/pico-1.5.9/css/pico.classless.min.css.map b/pico-1.5.9/css/pico.classless.min.css.map similarity index 100% rename from assets/pico-1.5.9/css/pico.classless.min.css.map rename to pico-1.5.9/css/pico.classless.min.css.map diff --git a/assets/pico-1.5.9/css/pico.css b/pico-1.5.9/css/pico.css similarity index 100% rename from assets/pico-1.5.9/css/pico.css rename to pico-1.5.9/css/pico.css diff --git a/assets/pico-1.5.9/css/pico.css.map b/pico-1.5.9/css/pico.css.map similarity index 100% rename from assets/pico-1.5.9/css/pico.css.map rename to pico-1.5.9/css/pico.css.map diff --git a/assets/pico-1.5.9/css/pico.fluid.classless.css b/pico-1.5.9/css/pico.fluid.classless.css similarity index 100% rename from assets/pico-1.5.9/css/pico.fluid.classless.css rename to pico-1.5.9/css/pico.fluid.classless.css diff --git a/assets/pico-1.5.9/css/pico.fluid.classless.css.map b/pico-1.5.9/css/pico.fluid.classless.css.map similarity index 100% rename from assets/pico-1.5.9/css/pico.fluid.classless.css.map rename to pico-1.5.9/css/pico.fluid.classless.css.map diff --git a/assets/pico-1.5.9/css/pico.fluid.classless.min.css b/pico-1.5.9/css/pico.fluid.classless.min.css similarity index 100% rename from assets/pico-1.5.9/css/pico.fluid.classless.min.css rename to pico-1.5.9/css/pico.fluid.classless.min.css diff --git a/assets/pico-1.5.9/css/pico.fluid.classless.min.css.map b/pico-1.5.9/css/pico.fluid.classless.min.css.map similarity index 100% rename from assets/pico-1.5.9/css/pico.fluid.classless.min.css.map rename to pico-1.5.9/css/pico.fluid.classless.min.css.map diff --git a/assets/pico-1.5.9/css/pico.min.css b/pico-1.5.9/css/pico.min.css similarity index 100% rename from assets/pico-1.5.9/css/pico.min.css rename to pico-1.5.9/css/pico.min.css diff --git a/assets/pico-1.5.9/css/pico.min.css.map b/pico-1.5.9/css/pico.min.css.map similarity index 100% rename from assets/pico-1.5.9/css/pico.min.css.map rename to pico-1.5.9/css/pico.min.css.map diff --git a/assets/pico-1.5.9/css/pico.slim.css b/pico-1.5.9/css/pico.slim.css similarity index 100% rename from assets/pico-1.5.9/css/pico.slim.css rename to pico-1.5.9/css/pico.slim.css diff --git a/assets/pico-1.5.9/css/pico.slim.css.map b/pico-1.5.9/css/pico.slim.css.map similarity index 100% rename from assets/pico-1.5.9/css/pico.slim.css.map rename to pico-1.5.9/css/pico.slim.css.map diff --git a/assets/pico-1.5.9/css/pico.slim.min.css b/pico-1.5.9/css/pico.slim.min.css similarity index 100% rename from assets/pico-1.5.9/css/pico.slim.min.css rename to pico-1.5.9/css/pico.slim.min.css diff --git a/assets/pico-1.5.9/css/pico.slim.min.css.map b/pico-1.5.9/css/pico.slim.min.css.map similarity index 100% rename from assets/pico-1.5.9/css/pico.slim.min.css.map rename to pico-1.5.9/css/pico.slim.min.css.map diff --git a/assets/pico-1.5.9/css/postcss.config.js b/pico-1.5.9/css/postcss.config.js similarity index 100% rename from assets/pico-1.5.9/css/postcss.config.js rename to pico-1.5.9/css/postcss.config.js diff --git a/assets/pico-1.5.9/css/themes/default.css b/pico-1.5.9/css/themes/default.css similarity index 100% rename from assets/pico-1.5.9/css/themes/default.css rename to pico-1.5.9/css/themes/default.css diff --git a/assets/pico-1.5.9/css/themes/default.css.map b/pico-1.5.9/css/themes/default.css.map similarity index 100% rename from assets/pico-1.5.9/css/themes/default.css.map rename to pico-1.5.9/css/themes/default.css.map diff --git a/assets/pico-1.5.9/css/themes/default.min.css b/pico-1.5.9/css/themes/default.min.css similarity index 100% rename from assets/pico-1.5.9/css/themes/default.min.css rename to pico-1.5.9/css/themes/default.min.css diff --git a/assets/pico-1.5.9/css/themes/default.min.css.map b/pico-1.5.9/css/themes/default.min.css.map similarity index 100% rename from assets/pico-1.5.9/css/themes/default.min.css.map rename to pico-1.5.9/css/themes/default.min.css.map diff --git a/assets/pico-1.5.9/docs/accordions.html b/pico-1.5.9/docs/accordions.html similarity index 100% rename from assets/pico-1.5.9/docs/accordions.html rename to pico-1.5.9/docs/accordions.html diff --git a/assets/pico-1.5.9/docs/buttons.html b/pico-1.5.9/docs/buttons.html similarity index 100% rename from assets/pico-1.5.9/docs/buttons.html rename to pico-1.5.9/docs/buttons.html diff --git a/assets/pico-1.5.9/docs/cards.html b/pico-1.5.9/docs/cards.html similarity index 100% rename from assets/pico-1.5.9/docs/cards.html rename to pico-1.5.9/docs/cards.html diff --git a/assets/pico-1.5.9/docs/classless.html b/pico-1.5.9/docs/classless.html similarity index 100% rename from assets/pico-1.5.9/docs/classless.html rename to pico-1.5.9/docs/classless.html diff --git a/assets/pico-1.5.9/docs/containers.html b/pico-1.5.9/docs/containers.html similarity index 100% rename from assets/pico-1.5.9/docs/containers.html rename to pico-1.5.9/docs/containers.html diff --git a/assets/pico-1.5.9/docs/css/pico.docs.css b/pico-1.5.9/docs/css/pico.docs.css similarity index 100% rename from assets/pico-1.5.9/docs/css/pico.docs.css rename to pico-1.5.9/docs/css/pico.docs.css diff --git a/assets/pico-1.5.9/docs/css/pico.docs.css.map b/pico-1.5.9/docs/css/pico.docs.css.map similarity index 100% rename from assets/pico-1.5.9/docs/css/pico.docs.css.map rename to pico-1.5.9/docs/css/pico.docs.css.map diff --git a/assets/pico-1.5.9/docs/css/pico.docs.min.css b/pico-1.5.9/docs/css/pico.docs.min.css similarity index 100% rename from assets/pico-1.5.9/docs/css/pico.docs.min.css rename to pico-1.5.9/docs/css/pico.docs.min.css diff --git a/assets/pico-1.5.9/docs/css/pico.docs.min.css.map b/pico-1.5.9/docs/css/pico.docs.min.css.map similarity index 100% rename from assets/pico-1.5.9/docs/css/pico.docs.min.css.map rename to pico-1.5.9/docs/css/pico.docs.min.css.map diff --git a/assets/pico-1.5.9/docs/customization.html b/pico-1.5.9/docs/customization.html similarity index 100% rename from assets/pico-1.5.9/docs/customization.html rename to pico-1.5.9/docs/customization.html diff --git a/assets/pico-1.5.9/docs/dropdowns.html b/pico-1.5.9/docs/dropdowns.html similarity index 100% rename from assets/pico-1.5.9/docs/dropdowns.html rename to pico-1.5.9/docs/dropdowns.html diff --git a/assets/pico-1.5.9/docs/forms.html b/pico-1.5.9/docs/forms.html similarity index 100% rename from assets/pico-1.5.9/docs/forms.html rename to pico-1.5.9/docs/forms.html diff --git a/assets/pico-1.5.9/docs/grid.html b/pico-1.5.9/docs/grid.html similarity index 100% rename from assets/pico-1.5.9/docs/grid.html rename to pico-1.5.9/docs/grid.html diff --git a/assets/pico-1.5.9/docs/index.html b/pico-1.5.9/docs/index.html similarity index 100% rename from assets/pico-1.5.9/docs/index.html rename to pico-1.5.9/docs/index.html diff --git a/assets/pico-1.5.9/docs/js/commons.js b/pico-1.5.9/docs/js/commons.js similarity index 100% rename from assets/pico-1.5.9/docs/js/commons.js rename to pico-1.5.9/docs/js/commons.js diff --git a/assets/pico-1.5.9/docs/js/commons.min.js b/pico-1.5.9/docs/js/commons.min.js similarity index 100% rename from assets/pico-1.5.9/docs/js/commons.min.js rename to pico-1.5.9/docs/js/commons.min.js diff --git a/assets/pico-1.5.9/docs/js/customization.js b/pico-1.5.9/docs/js/customization.js similarity index 100% rename from assets/pico-1.5.9/docs/js/customization.js rename to pico-1.5.9/docs/js/customization.js diff --git a/assets/pico-1.5.9/docs/js/customization.min.js b/pico-1.5.9/docs/js/customization.min.js similarity index 100% rename from assets/pico-1.5.9/docs/js/customization.min.js rename to pico-1.5.9/docs/js/customization.min.js diff --git a/assets/pico-1.5.9/docs/js/grid.js b/pico-1.5.9/docs/js/grid.js similarity index 100% rename from assets/pico-1.5.9/docs/js/grid.js rename to pico-1.5.9/docs/js/grid.js diff --git a/assets/pico-1.5.9/docs/js/grid.min.js b/pico-1.5.9/docs/js/grid.min.js similarity index 100% rename from assets/pico-1.5.9/docs/js/grid.min.js rename to pico-1.5.9/docs/js/grid.min.js diff --git a/assets/pico-1.5.9/docs/js/modal.js b/pico-1.5.9/docs/js/modal.js similarity index 100% rename from assets/pico-1.5.9/docs/js/modal.js rename to pico-1.5.9/docs/js/modal.js diff --git a/assets/pico-1.5.9/docs/js/modal.min.js b/pico-1.5.9/docs/js/modal.min.js similarity index 100% rename from assets/pico-1.5.9/docs/js/modal.min.js rename to pico-1.5.9/docs/js/modal.min.js diff --git a/assets/pico-1.5.9/docs/js/src/color-picker.js b/pico-1.5.9/docs/js/src/color-picker.js similarity index 100% rename from assets/pico-1.5.9/docs/js/src/color-picker.js rename to pico-1.5.9/docs/js/src/color-picker.js diff --git a/assets/pico-1.5.9/docs/js/src/material-design-colors.js b/pico-1.5.9/docs/js/src/material-design-colors.js similarity index 100% rename from assets/pico-1.5.9/docs/js/src/material-design-colors.js rename to pico-1.5.9/docs/js/src/material-design-colors.js diff --git a/assets/pico-1.5.9/docs/js/src/theme-switcher.js b/pico-1.5.9/docs/js/src/theme-switcher.js similarity index 100% rename from assets/pico-1.5.9/docs/js/src/theme-switcher.js rename to pico-1.5.9/docs/js/src/theme-switcher.js diff --git a/assets/pico-1.5.9/docs/js/src/toggle-navigation.js b/pico-1.5.9/docs/js/src/toggle-navigation.js similarity index 100% rename from assets/pico-1.5.9/docs/js/src/toggle-navigation.js rename to pico-1.5.9/docs/js/src/toggle-navigation.js diff --git a/assets/pico-1.5.9/docs/loading.html b/pico-1.5.9/docs/loading.html similarity index 100% rename from assets/pico-1.5.9/docs/loading.html rename to pico-1.5.9/docs/loading.html diff --git a/assets/pico-1.5.9/docs/modal.html b/pico-1.5.9/docs/modal.html similarity index 100% rename from assets/pico-1.5.9/docs/modal.html rename to pico-1.5.9/docs/modal.html diff --git a/assets/pico-1.5.9/docs/navs.html b/pico-1.5.9/docs/navs.html similarity index 100% rename from assets/pico-1.5.9/docs/navs.html rename to pico-1.5.9/docs/navs.html diff --git a/assets/pico-1.5.9/docs/progress.html b/pico-1.5.9/docs/progress.html similarity index 100% rename from assets/pico-1.5.9/docs/progress.html rename to pico-1.5.9/docs/progress.html diff --git a/assets/pico-1.5.9/docs/rtl.html b/pico-1.5.9/docs/rtl.html similarity index 100% rename from assets/pico-1.5.9/docs/rtl.html rename to pico-1.5.9/docs/rtl.html diff --git a/assets/pico-1.5.9/docs/scroller.html b/pico-1.5.9/docs/scroller.html similarity index 100% rename from assets/pico-1.5.9/docs/scroller.html rename to pico-1.5.9/docs/scroller.html diff --git a/assets/pico-1.5.9/docs/scss/components/_modal.scss b/pico-1.5.9/docs/scss/components/_modal.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/components/_modal.scss rename to pico-1.5.9/docs/scss/components/_modal.scss diff --git a/assets/pico-1.5.9/docs/scss/components/_nav.scss b/pico-1.5.9/docs/scss/components/_nav.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/components/_nav.scss rename to pico-1.5.9/docs/scss/components/_nav.scss diff --git a/assets/pico-1.5.9/docs/scss/components/_theme-switcher.scss b/pico-1.5.9/docs/scss/components/_theme-switcher.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/components/_theme-switcher.scss rename to pico-1.5.9/docs/scss/components/_theme-switcher.scss diff --git a/assets/pico-1.5.9/docs/scss/content/_code.scss b/pico-1.5.9/docs/scss/content/_code.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/content/_code.scss rename to pico-1.5.9/docs/scss/content/_code.scss diff --git a/assets/pico-1.5.9/docs/scss/content/_typography.scss b/pico-1.5.9/docs/scss/content/_typography.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/content/_typography.scss rename to pico-1.5.9/docs/scss/content/_typography.scss diff --git a/assets/pico-1.5.9/docs/scss/layout/_aside.scss b/pico-1.5.9/docs/scss/layout/_aside.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/layout/_aside.scss rename to pico-1.5.9/docs/scss/layout/_aside.scss diff --git a/assets/pico-1.5.9/docs/scss/layout/_document.scss b/pico-1.5.9/docs/scss/layout/_document.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/layout/_document.scss rename to pico-1.5.9/docs/scss/layout/_document.scss diff --git a/assets/pico-1.5.9/docs/scss/layout/_documentation.scss b/pico-1.5.9/docs/scss/layout/_documentation.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/layout/_documentation.scss rename to pico-1.5.9/docs/scss/layout/_documentation.scss diff --git a/assets/pico-1.5.9/docs/scss/layout/_main.scss b/pico-1.5.9/docs/scss/layout/_main.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/layout/_main.scss rename to pico-1.5.9/docs/scss/layout/_main.scss diff --git a/assets/pico-1.5.9/docs/scss/pico.docs.scss b/pico-1.5.9/docs/scss/pico.docs.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/pico.docs.scss rename to pico-1.5.9/docs/scss/pico.docs.scss diff --git a/assets/pico-1.5.9/docs/scss/themes/_docs.scss b/pico-1.5.9/docs/scss/themes/_docs.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/themes/_docs.scss rename to pico-1.5.9/docs/scss/themes/_docs.scss diff --git a/assets/pico-1.5.9/docs/scss/themes/docs/_dark.scss b/pico-1.5.9/docs/scss/themes/docs/_dark.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/themes/docs/_dark.scss rename to pico-1.5.9/docs/scss/themes/docs/_dark.scss diff --git a/assets/pico-1.5.9/docs/scss/themes/docs/_icons.scss b/pico-1.5.9/docs/scss/themes/docs/_icons.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/themes/docs/_icons.scss rename to pico-1.5.9/docs/scss/themes/docs/_icons.scss diff --git a/assets/pico-1.5.9/docs/scss/themes/docs/_light.scss b/pico-1.5.9/docs/scss/themes/docs/_light.scss similarity index 100% rename from assets/pico-1.5.9/docs/scss/themes/docs/_light.scss rename to pico-1.5.9/docs/scss/themes/docs/_light.scss diff --git a/assets/pico-1.5.9/docs/src/_footer.html b/pico-1.5.9/docs/src/_footer.html similarity index 100% rename from assets/pico-1.5.9/docs/src/_footer.html rename to pico-1.5.9/docs/src/_footer.html diff --git a/assets/pico-1.5.9/docs/src/_head.html b/pico-1.5.9/docs/src/_head.html similarity index 100% rename from assets/pico-1.5.9/docs/src/_head.html rename to pico-1.5.9/docs/src/_head.html diff --git a/assets/pico-1.5.9/docs/src/_nav.html b/pico-1.5.9/docs/src/_nav.html similarity index 100% rename from assets/pico-1.5.9/docs/src/_nav.html rename to pico-1.5.9/docs/src/_nav.html diff --git a/assets/pico-1.5.9/docs/src/_sidebar.html b/pico-1.5.9/docs/src/_sidebar.html similarity index 100% rename from assets/pico-1.5.9/docs/src/_sidebar.html rename to pico-1.5.9/docs/src/_sidebar.html diff --git a/assets/pico-1.5.9/docs/src/accordions.html b/pico-1.5.9/docs/src/accordions.html similarity index 100% rename from assets/pico-1.5.9/docs/src/accordions.html rename to pico-1.5.9/docs/src/accordions.html diff --git a/assets/pico-1.5.9/docs/src/buttons.html b/pico-1.5.9/docs/src/buttons.html similarity index 100% rename from assets/pico-1.5.9/docs/src/buttons.html rename to pico-1.5.9/docs/src/buttons.html diff --git a/assets/pico-1.5.9/docs/src/cards.html b/pico-1.5.9/docs/src/cards.html similarity index 100% rename from assets/pico-1.5.9/docs/src/cards.html rename to pico-1.5.9/docs/src/cards.html diff --git a/assets/pico-1.5.9/docs/src/classless.html b/pico-1.5.9/docs/src/classless.html similarity index 100% rename from assets/pico-1.5.9/docs/src/classless.html rename to pico-1.5.9/docs/src/classless.html diff --git a/assets/pico-1.5.9/docs/src/containers.html b/pico-1.5.9/docs/src/containers.html similarity index 100% rename from assets/pico-1.5.9/docs/src/containers.html rename to pico-1.5.9/docs/src/containers.html diff --git a/assets/pico-1.5.9/docs/src/customization.html b/pico-1.5.9/docs/src/customization.html similarity index 100% rename from assets/pico-1.5.9/docs/src/customization.html rename to pico-1.5.9/docs/src/customization.html diff --git a/assets/pico-1.5.9/docs/src/dropdowns.html b/pico-1.5.9/docs/src/dropdowns.html similarity index 100% rename from assets/pico-1.5.9/docs/src/dropdowns.html rename to pico-1.5.9/docs/src/dropdowns.html diff --git a/assets/pico-1.5.9/docs/src/forms.html b/pico-1.5.9/docs/src/forms.html similarity index 100% rename from assets/pico-1.5.9/docs/src/forms.html rename to pico-1.5.9/docs/src/forms.html diff --git a/assets/pico-1.5.9/docs/src/grid.html b/pico-1.5.9/docs/src/grid.html similarity index 100% rename from assets/pico-1.5.9/docs/src/grid.html rename to pico-1.5.9/docs/src/grid.html diff --git a/assets/pico-1.5.9/docs/src/index.html b/pico-1.5.9/docs/src/index.html similarity index 100% rename from assets/pico-1.5.9/docs/src/index.html rename to pico-1.5.9/docs/src/index.html diff --git a/assets/pico-1.5.9/docs/src/loading.html b/pico-1.5.9/docs/src/loading.html similarity index 100% rename from assets/pico-1.5.9/docs/src/loading.html rename to pico-1.5.9/docs/src/loading.html diff --git a/assets/pico-1.5.9/docs/src/modal.html b/pico-1.5.9/docs/src/modal.html similarity index 100% rename from assets/pico-1.5.9/docs/src/modal.html rename to pico-1.5.9/docs/src/modal.html diff --git a/assets/pico-1.5.9/docs/src/navs.html b/pico-1.5.9/docs/src/navs.html similarity index 100% rename from assets/pico-1.5.9/docs/src/navs.html rename to pico-1.5.9/docs/src/navs.html diff --git a/assets/pico-1.5.9/docs/src/progress.html b/pico-1.5.9/docs/src/progress.html similarity index 100% rename from assets/pico-1.5.9/docs/src/progress.html rename to pico-1.5.9/docs/src/progress.html diff --git a/assets/pico-1.5.9/docs/src/rtl.html b/pico-1.5.9/docs/src/rtl.html similarity index 100% rename from assets/pico-1.5.9/docs/src/rtl.html rename to pico-1.5.9/docs/src/rtl.html diff --git a/assets/pico-1.5.9/docs/src/scroller.html b/pico-1.5.9/docs/src/scroller.html similarity index 100% rename from assets/pico-1.5.9/docs/src/scroller.html rename to pico-1.5.9/docs/src/scroller.html diff --git a/assets/pico-1.5.9/docs/src/tables.html b/pico-1.5.9/docs/src/tables.html similarity index 100% rename from assets/pico-1.5.9/docs/src/tables.html rename to pico-1.5.9/docs/src/tables.html diff --git a/assets/pico-1.5.9/docs/src/themes.html b/pico-1.5.9/docs/src/themes.html similarity index 100% rename from assets/pico-1.5.9/docs/src/themes.html rename to pico-1.5.9/docs/src/themes.html diff --git a/assets/pico-1.5.9/docs/src/tooltips.html b/pico-1.5.9/docs/src/tooltips.html similarity index 100% rename from assets/pico-1.5.9/docs/src/tooltips.html rename to pico-1.5.9/docs/src/tooltips.html diff --git a/assets/pico-1.5.9/docs/src/typography.html b/pico-1.5.9/docs/src/typography.html similarity index 100% rename from assets/pico-1.5.9/docs/src/typography.html rename to pico-1.5.9/docs/src/typography.html diff --git a/assets/pico-1.5.9/docs/src/we-love-classes.html b/pico-1.5.9/docs/src/we-love-classes.html similarity index 100% rename from assets/pico-1.5.9/docs/src/we-love-classes.html rename to pico-1.5.9/docs/src/we-love-classes.html diff --git a/assets/pico-1.5.9/docs/tables.html b/pico-1.5.9/docs/tables.html similarity index 100% rename from assets/pico-1.5.9/docs/tables.html rename to pico-1.5.9/docs/tables.html diff --git a/assets/pico-1.5.9/docs/themes.html b/pico-1.5.9/docs/themes.html similarity index 100% rename from assets/pico-1.5.9/docs/themes.html rename to pico-1.5.9/docs/themes.html diff --git a/assets/pico-1.5.9/docs/tooltips.html b/pico-1.5.9/docs/tooltips.html similarity index 100% rename from assets/pico-1.5.9/docs/tooltips.html rename to pico-1.5.9/docs/tooltips.html diff --git a/assets/pico-1.5.9/docs/typography.html b/pico-1.5.9/docs/typography.html similarity index 100% rename from assets/pico-1.5.9/docs/typography.html rename to pico-1.5.9/docs/typography.html diff --git a/assets/pico-1.5.9/docs/we-love-classes.html b/pico-1.5.9/docs/we-love-classes.html similarity index 100% rename from assets/pico-1.5.9/docs/we-love-classes.html rename to pico-1.5.9/docs/we-love-classes.html diff --git a/assets/pico-1.5.9/package-lock.json b/pico-1.5.9/package-lock.json similarity index 100% rename from assets/pico-1.5.9/package-lock.json rename to pico-1.5.9/package-lock.json diff --git a/assets/pico-1.5.9/package.json b/pico-1.5.9/package.json similarity index 100% rename from assets/pico-1.5.9/package.json rename to pico-1.5.9/package.json diff --git a/assets/pico-1.5.9/scss/_functions.scss b/pico-1.5.9/scss/_functions.scss similarity index 100% rename from assets/pico-1.5.9/scss/_functions.scss rename to pico-1.5.9/scss/_functions.scss diff --git a/assets/pico-1.5.9/scss/_variables.scss b/pico-1.5.9/scss/_variables.scss similarity index 100% rename from assets/pico-1.5.9/scss/_variables.scss rename to pico-1.5.9/scss/_variables.scss diff --git a/assets/pico-1.5.9/scss/components/_accordion.scss b/pico-1.5.9/scss/components/_accordion.scss similarity index 100% rename from assets/pico-1.5.9/scss/components/_accordion.scss rename to pico-1.5.9/scss/components/_accordion.scss diff --git a/assets/pico-1.5.9/scss/components/_card.scss b/pico-1.5.9/scss/components/_card.scss similarity index 100% rename from assets/pico-1.5.9/scss/components/_card.scss rename to pico-1.5.9/scss/components/_card.scss diff --git a/assets/pico-1.5.9/scss/components/_dropdown.scss b/pico-1.5.9/scss/components/_dropdown.scss similarity index 100% rename from assets/pico-1.5.9/scss/components/_dropdown.scss rename to pico-1.5.9/scss/components/_dropdown.scss diff --git a/assets/pico-1.5.9/scss/components/_modal.scss b/pico-1.5.9/scss/components/_modal.scss similarity index 100% rename from assets/pico-1.5.9/scss/components/_modal.scss rename to pico-1.5.9/scss/components/_modal.scss diff --git a/assets/pico-1.5.9/scss/components/_nav.scss b/pico-1.5.9/scss/components/_nav.scss similarity index 100% rename from assets/pico-1.5.9/scss/components/_nav.scss rename to pico-1.5.9/scss/components/_nav.scss diff --git a/assets/pico-1.5.9/scss/components/_progress.scss b/pico-1.5.9/scss/components/_progress.scss similarity index 100% rename from assets/pico-1.5.9/scss/components/_progress.scss rename to pico-1.5.9/scss/components/_progress.scss diff --git a/assets/pico-1.5.9/scss/content/_button.scss b/pico-1.5.9/scss/content/_button.scss similarity index 100% rename from assets/pico-1.5.9/scss/content/_button.scss rename to pico-1.5.9/scss/content/_button.scss diff --git a/assets/pico-1.5.9/scss/content/_code.scss b/pico-1.5.9/scss/content/_code.scss similarity index 100% rename from assets/pico-1.5.9/scss/content/_code.scss rename to pico-1.5.9/scss/content/_code.scss diff --git a/assets/pico-1.5.9/scss/content/_embedded.scss b/pico-1.5.9/scss/content/_embedded.scss similarity index 100% rename from assets/pico-1.5.9/scss/content/_embedded.scss rename to pico-1.5.9/scss/content/_embedded.scss diff --git a/assets/pico-1.5.9/scss/content/_form-alt-input-types.scss b/pico-1.5.9/scss/content/_form-alt-input-types.scss similarity index 100% rename from assets/pico-1.5.9/scss/content/_form-alt-input-types.scss rename to pico-1.5.9/scss/content/_form-alt-input-types.scss diff --git a/assets/pico-1.5.9/scss/content/_form-checkbox-radio.scss b/pico-1.5.9/scss/content/_form-checkbox-radio.scss similarity index 100% rename from assets/pico-1.5.9/scss/content/_form-checkbox-radio.scss rename to pico-1.5.9/scss/content/_form-checkbox-radio.scss diff --git a/assets/pico-1.5.9/scss/content/_form.scss b/pico-1.5.9/scss/content/_form.scss similarity index 100% rename from assets/pico-1.5.9/scss/content/_form.scss rename to pico-1.5.9/scss/content/_form.scss diff --git a/assets/pico-1.5.9/scss/content/_miscs.scss b/pico-1.5.9/scss/content/_miscs.scss similarity index 100% rename from assets/pico-1.5.9/scss/content/_miscs.scss rename to pico-1.5.9/scss/content/_miscs.scss diff --git a/assets/pico-1.5.9/scss/content/_table.scss b/pico-1.5.9/scss/content/_table.scss similarity index 100% rename from assets/pico-1.5.9/scss/content/_table.scss rename to pico-1.5.9/scss/content/_table.scss diff --git a/assets/pico-1.5.9/scss/content/_typography.scss b/pico-1.5.9/scss/content/_typography.scss similarity index 100% rename from assets/pico-1.5.9/scss/content/_typography.scss rename to pico-1.5.9/scss/content/_typography.scss diff --git a/assets/pico-1.5.9/scss/layout/_container.scss b/pico-1.5.9/scss/layout/_container.scss similarity index 100% rename from assets/pico-1.5.9/scss/layout/_container.scss rename to pico-1.5.9/scss/layout/_container.scss diff --git a/assets/pico-1.5.9/scss/layout/_document.scss b/pico-1.5.9/scss/layout/_document.scss similarity index 100% rename from assets/pico-1.5.9/scss/layout/_document.scss rename to pico-1.5.9/scss/layout/_document.scss diff --git a/assets/pico-1.5.9/scss/layout/_grid.scss b/pico-1.5.9/scss/layout/_grid.scss similarity index 100% rename from assets/pico-1.5.9/scss/layout/_grid.scss rename to pico-1.5.9/scss/layout/_grid.scss diff --git a/assets/pico-1.5.9/scss/layout/_scroller.scss b/pico-1.5.9/scss/layout/_scroller.scss similarity index 100% rename from assets/pico-1.5.9/scss/layout/_scroller.scss rename to pico-1.5.9/scss/layout/_scroller.scss diff --git a/assets/pico-1.5.9/scss/layout/_section.scss b/pico-1.5.9/scss/layout/_section.scss similarity index 100% rename from assets/pico-1.5.9/scss/layout/_section.scss rename to pico-1.5.9/scss/layout/_section.scss diff --git a/assets/pico-1.5.9/scss/layout/_sectioning.scss b/pico-1.5.9/scss/layout/_sectioning.scss similarity index 100% rename from assets/pico-1.5.9/scss/layout/_sectioning.scss rename to pico-1.5.9/scss/layout/_sectioning.scss diff --git a/assets/pico-1.5.9/scss/pico.classless.scss b/pico-1.5.9/scss/pico.classless.scss similarity index 100% rename from assets/pico-1.5.9/scss/pico.classless.scss rename to pico-1.5.9/scss/pico.classless.scss diff --git a/assets/pico-1.5.9/scss/pico.fluid.classless.scss b/pico-1.5.9/scss/pico.fluid.classless.scss similarity index 100% rename from assets/pico-1.5.9/scss/pico.fluid.classless.scss rename to pico-1.5.9/scss/pico.fluid.classless.scss diff --git a/assets/pico-1.5.9/scss/pico.scss b/pico-1.5.9/scss/pico.scss similarity index 100% rename from assets/pico-1.5.9/scss/pico.scss rename to pico-1.5.9/scss/pico.scss diff --git a/assets/pico-1.5.9/scss/pico.slim.scss b/pico-1.5.9/scss/pico.slim.scss similarity index 100% rename from assets/pico-1.5.9/scss/pico.slim.scss rename to pico-1.5.9/scss/pico.slim.scss diff --git a/assets/pico-1.5.9/scss/postcss.config.js b/pico-1.5.9/scss/postcss.config.js similarity index 100% rename from assets/pico-1.5.9/scss/postcss.config.js rename to pico-1.5.9/scss/postcss.config.js diff --git a/assets/pico-1.5.9/scss/themes/default.scss b/pico-1.5.9/scss/themes/default.scss similarity index 100% rename from assets/pico-1.5.9/scss/themes/default.scss rename to pico-1.5.9/scss/themes/default.scss diff --git a/assets/pico-1.5.9/scss/themes/default/_colors.scss b/pico-1.5.9/scss/themes/default/_colors.scss similarity index 100% rename from assets/pico-1.5.9/scss/themes/default/_colors.scss rename to pico-1.5.9/scss/themes/default/_colors.scss diff --git a/assets/pico-1.5.9/scss/themes/default/_dark.scss b/pico-1.5.9/scss/themes/default/_dark.scss similarity index 100% rename from assets/pico-1.5.9/scss/themes/default/_dark.scss rename to pico-1.5.9/scss/themes/default/_dark.scss diff --git a/assets/pico-1.5.9/scss/themes/default/_light.scss b/pico-1.5.9/scss/themes/default/_light.scss similarity index 100% rename from assets/pico-1.5.9/scss/themes/default/_light.scss rename to pico-1.5.9/scss/themes/default/_light.scss diff --git a/assets/pico-1.5.9/scss/themes/default/_styles.scss b/pico-1.5.9/scss/themes/default/_styles.scss similarity index 100% rename from assets/pico-1.5.9/scss/themes/default/_styles.scss rename to pico-1.5.9/scss/themes/default/_styles.scss diff --git a/assets/pico-1.5.9/scss/utilities/_accessibility.scss b/pico-1.5.9/scss/utilities/_accessibility.scss similarity index 100% rename from assets/pico-1.5.9/scss/utilities/_accessibility.scss rename to pico-1.5.9/scss/utilities/_accessibility.scss diff --git a/assets/pico-1.5.9/scss/utilities/_loading.scss b/pico-1.5.9/scss/utilities/_loading.scss similarity index 100% rename from assets/pico-1.5.9/scss/utilities/_loading.scss rename to pico-1.5.9/scss/utilities/_loading.scss diff --git a/assets/pico-1.5.9/scss/utilities/_reduce-motion.scss b/pico-1.5.9/scss/utilities/_reduce-motion.scss similarity index 100% rename from assets/pico-1.5.9/scss/utilities/_reduce-motion.scss rename to pico-1.5.9/scss/utilities/_reduce-motion.scss diff --git a/assets/pico-1.5.9/scss/utilities/_tooltip.scss b/pico-1.5.9/scss/utilities/_tooltip.scss similarity index 100% rename from assets/pico-1.5.9/scss/utilities/_tooltip.scss rename to pico-1.5.9/scss/utilities/_tooltip.scss diff --git a/assets/pico.classless.min.css b/pico.classless.min.css similarity index 100% rename from assets/pico.classless.min.css rename to pico.classless.min.css diff --git a/src/app.rs b/src/app.rs new file mode 100644 index 0000000..8c89a15 --- /dev/null +++ b/src/app.rs @@ -0,0 +1,35 @@ +use dioxus::prelude::*; +use dioxus_router::prelude::*; + +use slpprocess::GameStub; +use ssbm_utils::enums::Character; +use crate::pages::{ + StatsPage, + Browse +}; + +pub struct WorkingDir(pub String); +pub struct Stubs(pub Vec); +pub struct Sets(pub Vec<(usize, usize)>); + +#[derive(Debug, Default, PartialEq, Eq, Clone)] +pub struct Filters { + pub code: String, + pub display_name: String, + pub character: Option, +} + +pub fn app(cx: Scope) -> Element { + use_shared_state_provider(cx, || WorkingDir("".to_string())); + use_shared_state_provider(cx, || Stubs(Vec::::new())); + use_shared_state_provider(cx, || Sets(Vec::new())); + render! { Router:: {} } +} + +#[derive(Clone, Routable, PartialEq)] +pub enum Route { + #[route("/")] + Browse {}, + #[route("/stats")] + StatsPage { index: usize }, +} \ No newline at end of file diff --git a/src/cards.rs b/src/cards.rs deleted file mode 100644 index b5e1855..0000000 --- a/src/cards.rs +++ /dev/null @@ -1,60 +0,0 @@ -use dioxus::prelude::*; -use dioxus_router::components::Link; -use slpprocess::game::GameStub; -use time::UtcOffset; - -use crate::Route; - -#[inline_props] -pub fn Card(cx: Scope, stub: GameStub) -> Element { - let date = stub.metadata.date; - let time = date.to_offset(UtcOffset::current_local_offset().unwrap()).time(); - let date_str = format!( - "{} {} {}, {} at {:0>2}:{:0>2}:{:0>2}", - date.weekday(), - date.month(), - date.day(), - date.year(), - time.hour(), - time.minute(), - time.second(), - ); - - let p1 = &stub.players[0]; - let p2 = &stub.players[1]; - cx.render(rsx! { - button { - background_color: "#11191f", - Link { - to: Route::StatsPage { - path: stub.path.clone(), - }, - header { - - div { - display: "flex", - justify_content: "space-between", - p { - color: "#fff", - font_size: "75%", - "{date_str}" - } - p {color: "#fff", "{stub.metadata.stage.to_string()}"} - p { - color: "#fff", - font_size: "75%", - "{stub.path.file_name().unwrap().to_str().unwrap()}" - } - } - } - div { - display: "flex", - gap: "20em", - justify_content: "space-evenly", - p {color: "#fff", "{stub.players[0].display_name.clone().unwrap_or_default()} ({stub.players[0].connect_code.clone().unwrap_or_default()}) | {stub.players[0].character.to_string()}" } - p {color: "#fff", "{stub.players[1].display_name.clone().unwrap_or_default()} ({stub.players[1].connect_code.clone().unwrap_or_default()}) | {stub.players[1].character.to_string()}"} - } - } - } - }) -} diff --git a/src/components/assets.rs b/src/components/assets.rs new file mode 100644 index 0000000..ec778bb --- /dev/null +++ b/src/components/assets.rs @@ -0,0 +1,25 @@ +use dioxus::prelude::*; +use ssbm_utils::prelude::*; + +#[component] +pub fn StockIcon(cx: Scope, character: (Character, Costume), opacity: Option) -> Element { + render! ( + img { + height: "24px", + width: "24px", + opacity: "{opacity.unwrap_or(1.0)}", + src: "./dist/Characters/{character.0.to_string()}/{character.1.to_string()}.png" + } + ) +} + +#[component] +pub fn StageImg(cx: Scope, stage: StageID) -> Element { + render!( + img { + height: "48px", + width: "64px", + src: "./dist/Stages/{stage.to_string()}.png" + } + ) +} \ No newline at end of file diff --git a/src/components/cards.rs b/src/components/cards.rs new file mode 100644 index 0000000..a5876c2 --- /dev/null +++ b/src/components/cards.rs @@ -0,0 +1,264 @@ +use std::collections::{HashSet, HashMap}; + +use counter::Counter; +use dioxus::{prelude::*, html::SvgAttributes}; +use dioxus_router::prelude::*; +use slpprocess::game::{Game, GameStub, GameMetadata}; +use ssbm_utils::enums::{Character, Costume, StageID}; +use time::UtcOffset; + +use crate::{app::{Route, Stubs, Filters}, utils::filter_game, components::StockIcon}; + +#[component] +pub fn Card(cx: Scope, set: (usize, usize), filters: Filters) -> Element { + let stubs = use_shared_state::(cx).unwrap(); + let games = &stubs.read().0[set.0..set.1]; + let stub = games[0].clone(); + + let full_set: &UseRef> = use_ref(cx, Vec::new); + + let date = stub.date; + + let date_str = format!( + "{} {} {}, {}", + date.weekday(), + date.month(), + date.day(), + date.year(), + ); + + let p1 = &stub.players[0]; + let p2 = &stub.players[1]; + + let mut p1_map: HashMap> = HashMap::new(); + let mut p2_map: HashMap> = HashMap::new(); + + + + for game in games { + *p1_map.entry(game.players[0].character).or_default().entry(game.players[0].costume).or_default() += 1; + *p2_map.entry(game.players[1].character).or_default().entry(game.players[1].costume).or_default() += 1; + // if p1_chars.contains_key(&game.players[0].character) { + // p1_chars[&game.players[0].character][&game.players[0].costume] += 1; + // } else { + + // } + } + let mut p1_chars = Vec::new(); + for (k, v) in p1_map { + p1_chars.push((k, v.total::(), v.most_common()[0].0)) + } + + p1_chars.sort_by(|a, b| b.1.cmp(&a.1)); + + let mut p2_chars = Vec::new(); + for (k, v) in p2_map { + p2_chars.push((k, v.total::(), v.most_common()[0].0)) + } + + p2_chars.sort_by(|a, b| b.1.cmp(&a.1)); + + // let p1_chars = games + // .iter() + // .map(|g| g.players[0].character) + // .collect::>().most_common(); + // let p2_chars = games + // .iter() + // .map(|g| g.players[1].character) + // .collect::>().most_common(); + + let navigator = use_navigator(cx); + + let filtered = if stubs.read().0[set.0..set.1].iter().any(|g| filter_game(g, filters)) { "initial" } else { "none" }; + + + render!( + div { + display: "{filtered}", + details { + summary { class: "none", + article { class: "background no-elevate", + onclick: |_evt| { + to_owned!(stubs); + if full_set.read().is_empty() { + *full_set.write() = stubs.read().0[set.0..set.1].iter().map(Into::::into).collect(); + } + }, + div { class: "row", + p { class: "max", color: "#999", "{format_time(&stub)}" } + p { class: "max", color: "#999", "{date_str}" } + p { color: "#999", "{games[0].match_type().to_string()}" } + } + nav { class: "center-align medium-space", + i { visibility: "hidden", "expand_more" } + div { class: "max", + div { + for (chr,_, cost) in p1_chars { + render!( + StockIcon { character: (chr, cost)} + ) + } + } + div { + b { "{p1.display_name.clone().unwrap_or_else(|| p1.port.to_string())} " } + p { color: "#999", font_size: "80%", + "{p1.connect_code.clone().unwrap_or_default()}" + } + } + } + div { class: "max", + div { + for (chr, _, cost) in p2_chars { + render!( + StockIcon { character: (chr, cost)} + ) + } + } + div { + b { "{p2.display_name.clone().unwrap_or_else(|| p2.port.to_string())} " } + p { color: "#999", font_size: "80%", + "{p2.connect_code.clone().unwrap_or_default()}" + } + } + } + i { "expand_more" } + } + } + } + table { class: "stripes center-align", + tbody { + for (i, game) in full_set.read().iter().enumerate() { + render!( + // println!("./dist/Stages/{}.png", game.stage().to_string()) + tr { + onclick: move |_| {navigator.push(Route::StatsPage { index: i + set.0 });}, + td { + text_align: "right", + StockIcon { character: (game.players[0].character, game.players[0].costume), opacity: if game.players[0].frames.post.stocks[game.players[0].frames.len() - 1] == 4 { 1.0 } else { 0.25 }} + StockIcon { character: (game.players[0].character, game.players[0].costume), opacity: if game.players[0].frames.post.stocks[game.players[0].frames.len() - 1] >= 3 { 1.0 } else { 0.25 }} + StockIcon { character: (game.players[0].character, game.players[0].costume), opacity: if game.players[0].frames.post.stocks[game.players[0].frames.len() - 1] >= 2 { 1.0 } else { 0.25 }} + StockIcon { character: (game.players[0].character, game.players[0].costume), opacity: if game.players[0].frames.post.stocks[game.players[0].frames.len() - 1] >= 1 { 1.0 } else { 0.25 }} + // img { + // height: "24px", + // width: "24px", + // src: "./dist/Characters/{game.players[0].character.to_string()}/{game.players[0].costume.to_string()}.png", + // opacity: "{(game.players[0].frames.post.stocks[game.players[0].frames.len() - 1] == 4).then_some(1.0).unwrap_or(0.5)}", + // } + // img { + // height: "24px", + // width: "24px", + // src: "./dist/Characters/{game.players[0].character.to_string()}/{game.players[0].costume.to_string()}.png", + // opacity: "{(game.players[0].frames.post.stocks[game.players[0].frames.len() - 1] >= 3).then_some(1.0).unwrap_or(0.5)}", + // } + // img { + // height: "24px", + // width: "24px", + // src: "./dist/Characters/{game.players[0].character.to_string()}/{game.players[0].costume.to_string()}.png", + // opacity: "{(game.players[0].frames.post.stocks[game.players[0].frames.len() - 1] >= 2).then_some(1.0).unwrap_or(0.5)}", + // } + // img { + // height: "24px", + // width: "24px", + // src: "./dist/Characters/{game.players[0].character.to_string()}/{game.players[0].costume.to_string()}.png", + // opacity: "{(game.players[0].frames.post.stocks[game.players[0].frames.len() - 1] >= 1).then_some(1.0).unwrap_or(0.5)}", + // } + } + td { + + p { "{format_time(game)}"} + img { + height: "48px", + width: "64px", + src: "./dist/Stages/{game.stage().to_string()}.png" + } + p { "{format_duration(game)}"} + } + td{ + text_align: "left", + StockIcon { character: (game.players[1].character, game.players[1].costume), opacity: if game.players[1].frames.post.stocks[game.players[1].frames.len() - 1] >= 1 { 1.0 } else { 0.25 }} + StockIcon { character: (game.players[1].character, game.players[1].costume), opacity: if game.players[1].frames.post.stocks[game.players[1].frames.len() - 1] >= 2 { 1.0 } else { 0.25 }} + StockIcon { character: (game.players[1].character, game.players[1].costume), opacity: if game.players[1].frames.post.stocks[game.players[1].frames.len() - 1] >= 3 { 1.0 } else { 0.25 }} + StockIcon { character: (game.players[1].character, game.players[1].costume), opacity: if game.players[1].frames.post.stocks[game.players[1].frames.len() - 1] == 4 { 1.0 } else { 0.25 }} + // img { + // height: "24px", + // width: "24px", + // src: "./dist/Characters/{game.players[1].character.to_string()}/{game.players[1].costume.to_string()}.png", + + // opacity: "{(game.players[1].frames.post.stocks[game.players[1].frames.len() - 1] >= 1).then_some(1.0).unwrap_or(0.5)}", + // } + // img { + // height: "24px", + // width: "24px", + // src: "./dist/Characters/{game.players[1].character.to_string()}/{game.players[1].costume.to_string()}.png", + + // opacity: "{(game.players[1].frames.post.stocks[game.players[1].frames.len() - 1] >= 2).then_some(1.0).unwrap_or(0.5)}", + // } + // img { + // height: "24px", + // width: "24px", + // src: "./dist/Characters/{game.players[1].character.to_string()}/{game.players[1].costume.to_string()}.png", + + // opacity: "{(game.players[1].frames.post.stocks[game.players[1].frames.len() - 1] >= 3).then_some(1.0).unwrap_or(0.5)}", + // } + // img { + // height: "24px", + // width: "24px", + // src: "./dist/Characters/{game.players[1].character.to_string()}/{game.players[1].costume.to_string()}.png", + + // opacity: "{(game.players[1].frames.post.stocks[game.players[1].frames.len() - 1] == 4).then_some(1.0).unwrap_or(0.5)}", + // } + } + } + ) + } + } + } + + } + div { class: "space"} + } + ) +} + +fn stage_string(stage: StageID) -> &'static str { + match stage { + StageID::FOUNTAIN_OF_DREAMS => "Fountain of Dreams", + StageID::POKEMON_STADIUM => "Pokemon Stadium", + StageID::YOSHIS_STORY => "Yoshi's Story", + StageID::DREAM_LAND_N64 => "Dreamland", + StageID::BATTLEFIELD => "Battlefield", + StageID::FINAL_DESTINATION => "Final Destination", + _ => stage.into(), + } +} + +fn format_time(game: &G) -> String { + let time = game + .date() + .to_offset(UtcOffset::current_local_offset().unwrap()) + .time(); + + // this whole thing is pretty ick but oh well + let hour = time.hour(); + let time_str = format!( + "{: >2}:{:0>2}:{:0>2}{}", + match hour { + x if x > 12 => x - 12, + 0 => 12, + x => x, + }, + time.minute(), + time.second(), + match hour { + _ if hour >= 12 => "pm", + _ => "am", + }, + ); + + time_str +} + +fn format_duration(game: &G) -> String { + let mins = game.duration().as_secs() / 60; + format!("{}m{:0>2}s", mins, game.duration().as_secs() - (60 * mins)) +} diff --git a/src/components/head.rs b/src/components/head.rs new file mode 100644 index 0000000..deba8cb --- /dev/null +++ b/src/components/head.rs @@ -0,0 +1,14 @@ +use dioxus::prelude::*; +use dioxus_router::prelude::*; + +#[component] +pub fn DefaultHead(cx: Scope) -> Element { + render!( + head { + link { rel: "stylesheet", href: "./dist/beer.min.css" } + script { r#type: "module", src: "./dist/beer.min.js" } + script { r#type: "module", src: "./dist/material-dynamic-colors.min.js" } + script { src: "maintainscroll.js" } + } + ) +} diff --git a/src/table.rs b/src/components/table.rs similarity index 75% rename from src/table.rs rename to src/components/table.rs index 8eb0314..15cd3c5 100644 --- a/src/table.rs +++ b/src/components/table.rs @@ -4,55 +4,60 @@ use dioxus::prelude::*; use polars::prelude::*; -#[inline_props] +#[component(no_case_check)] pub fn DFTable(cx: Scope, dataframe: DataFrame) -> Element { let height = dataframe.height(); let column_names = dataframe.get_column_names(); let columns = dataframe.get_columns(); let selected = use_state(cx, || usize::MAX); - let highlighted = "rgba(16, 149, 193, 0.125)"; - cx.render(rsx!( - table { role: "grid", margin: 0, padding: 0, - thead { - tr { - for name in column_names { - th { - scope: "col", - position: "sticky", - top: "0", - b{ - font_size: "16px", - "{name}" + let highlighted = "#442a20"; + render!( + table { class: "border stripes", margin: 0, padding: 0, + thead { class: "fixed", + tr { + for name in column_names { + th { + scope: "col", + position: "sticky", + top: "0", + b{ + font_size: "16px", + "{name}", + div { class: "tooltip bottom", + "eef" + } + } + } } } } - } - tbody { - for i in 0..height { - tr { - id: "{i}", - background_color: "{(*selected == i).then(|| highlighted).unwrap_or(\"#11191f\")} ", - onclick: move |evt| { - if *selected == i { - selected.set(usize::MAX); - } else { - selected.set(i); - } - }, - for column in columns { - td { text_wrap: "nowrap", - { - let val = column.get(i).unwrap(); - anyval_to_string(&val) + tbody { + for i in 0..height { + tr { + id: "{i}", + background_color: "{ + (*selected == i).then(|| highlighted).unwrap_or_else(|| (i & 1 == 0).then_some(\"rgb(255 255 255 / .00)\").unwrap_or(\"rgb(255 255 255 / .05)\"))} ", + onclick: move |evt| { + if *selected == i { + selected.set(usize::MAX); + } else { + selected.set(i); + } + }, + for column in columns { + td { text_wrap: "nowrap", + { + let val = column.get(i).unwrap(); + anyval_to_string(&val) + } } } } } } - } } - )) + ) } /// **Recursive** @@ -67,14 +72,14 @@ pub fn anyval_to_string(val: &datatypes::AnyValue) -> String { // handle nested data datatypes::AnyValue::Struct(_, _, c) => { - let mut temp = "{".to_string(); + let mut temp = "".to_string(); let mut buf = Vec::new(); val._materialize_struct_av(&mut buf); for (field, data) in zip(c.iter(), buf.iter()) { - temp.push_str(&format!("{}: {}, ", field.name, anyval_to_string(data))); + temp.push_str(&format!("{}: {}, ", field.name.to_uppercase(), anyval_to_string(data))); } temp = temp[0..temp.len() - 2].to_string(); - temp.push('}'); + // temp.push('}'); temp } @@ -100,7 +105,7 @@ pub fn anyval_to_string(val: &datatypes::AnyValue) -> String { datatypes::AnyValue::Boolean(x) => match x { true => "✓".to_string(), false => "X".to_string(), - } + }, // datatypes::AnyValue::Datetime(x, y, z) => { // chrono::DateTime::::from_naive_utc_and_offset( // chrono::naive::NaiveDateTime::from_timestamp_micros(x / 1000).unwrap(), diff --git a/src/top_bar.rs b/src/components/top_bar.rs similarity index 69% rename from src/top_bar.rs rename to src/components/top_bar.rs index 23c8193..2ea72f3 100644 --- a/src/top_bar.rs +++ b/src/components/top_bar.rs @@ -1,18 +1,14 @@ -use std::iter::zip; -use std::str::FromStr; - -use dioxus_router::prelude::*; - use dioxus::prelude::*; -use log::LevelFilter; +use dioxus_router::prelude::*; +use std::str::FromStr; use polars::prelude::*; use slpprocess::{parse, player::Player, stats::StatType, Game}; use ssbm_utils::enums::Port; -use crate::Route; +use crate::app::Route; -#[inline_props] +#[component] pub fn TopBar<'a>( cx: Scope<'a>, players: [Arc; 2], @@ -21,23 +17,8 @@ pub fn TopBar<'a>( ) -> Element { cx.render(rsx!( nav { gap: "20px", - Link { to: Route::Home {}, button { flex: "0 0 auto", r#type: "button", "Back" } } - // input { - // flex: "0 0 auto", - // r#type: "file", - // id: "file_input", - // accept: ".slp", - // overflow: "hidden", - // max_width: "6.5rem", - // onchange: |evt| { - // let fs = evt.files.as_ref().unwrap().files(); - // let file = &fs.get(0); - // if file.is_some() { - // let mut g = games.write(); - // *g = Some(parse(file.unwrap(), true)); - // } - // } - // } + Link { to: Route::Browse {}, button { flex: "0 0 auto", r#type: "button", "Back" } } + div { input { r#type: "radio", @@ -48,10 +29,10 @@ pub fn TopBar<'a>( onclick: |_evt| { let mut p = port.write(); *p = players[0].port; - }, + } } label { r#for: "player_1", - "{players[0].connect_code.clone().unwrap_or(Port::P1.to_string())} | {players[0].character.to_string()}" + "{players[0].connect_code.clone().unwrap_or(Port::P1.to_string())} | {players[0].character.to_string()}" } } diff --git a/src/con_code.rs b/src/con_code.rs deleted file mode 100644 index 488cf3a..0000000 --- a/src/con_code.rs +++ /dev/null @@ -1,23 +0,0 @@ -// input { -// r#type: "text", -// placeholder: "Connect Code (e.g. CODE#123)", -// maxlength: 8, -// pattern: regex, -// oninvalid: |ev| {}, -// onchange: |ev| { -// connect_code.set(ev.value.clone()); -// if game.read().is_some() { -// df.set( -// game -// .read() -// .as_ref() -// .unwrap() -// .player_by_code(&connect_code.read()) -// .unwrap() -// .stats -// .get(*stat_type.read()) -// .unwrap(), -// ); -// } -// } -// } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 692c41a..3d32768 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,150 +1,88 @@ #![allow(non_snake_case)] -mod table; -use slpprocess::game::GameStub; -use slpprocess::{parse_stubs, Game}; -use table::*; -mod top_bar; -use top_bar::*; -mod cards; -use cards::*; - -use std::str::FromStr; -use std::{iter::zip, path::PathBuf}; - -use dioxus_router::prelude::*; - -use dioxus::prelude::*; -use log::LevelFilter; - -use polars::prelude::*; -use slpprocess::{parse, stats::StatType, Port}; - -pub struct WorkingDir(String); -pub struct Stubs(Vec); - -pub fn app(cx: Scope) -> Element { - use_shared_state_provider(cx, || WorkingDir("".to_string())); - use_shared_state_provider(cx, || Stubs(Vec::::new())); - render! { Router:: {} } +pub mod app; +pub mod pages { + pub mod browse; + pub use browse::Browse; + pub mod stats; + pub use stats::StatsPage; } +pub mod components { + pub mod table; + pub use table::DFTable; -#[derive(Clone, Routable, Debug, PartialEq)] -pub enum Route { - #[route("/")] - Home {}, - #[route("/stats")] - StatsPage {path: Arc}, -} + pub mod top_bar; + pub use top_bar::TopBar; -#[inline_props] -pub fn Home(cx: Scope) -> Element { - let working_dir = use_shared_state::(cx).unwrap(); - let stubs = use_shared_state::(cx).unwrap(); + pub mod cards; + pub use cards::Card; - cx.render(rsx! { - head { link { rel: "stylesheet", href: "./dist/pico.classless.min.css" } } - body {margin: 0, padding: "10px", - nav { gap: "20px", - input { - flex: "0 0 auto", - r#type: "file", - id: "file_input", - directory: true, - overflow: "hidden", - max_width: "6.5rem", - onchange: |evt| { - let fs = evt.files.as_ref().unwrap().files(); - let file = &fs.get(0); - if let Some(f) = file { - working_dir.write().0 = f.to_string(); - stubs.write().0 = parse_stubs(f, true); - } - } - } - } + pub mod head; + pub use head::DefaultHead; - for stub in &*stubs.read().0 { - rsx!( - Card { stub: stub.clone()} - ) - } - } - }) + pub mod assets; + pub use assets::{StockIcon, StageImg}; +} +pub mod utils; + +// TODO move this to slpprocess +#[macro_export] +macro_rules! static_str { + ($x:expr) => { + Into::<&'static str>::into($x) + } } -#[inline_props] -pub fn StatsPage(cx: Scope, path: Arc) -> Element { - let game = use_ref(cx, || parse(path.to_str().unwrap(), false).pop().unwrap()); - let port: &UseRef = use_ref(cx, || Port::P1); - let stat_type: &UseRef = use_ref(cx, || StatType::Defense); - - cx.render(rsx! { - head { link { rel: "stylesheet", href: "./dist/pico.classless.min.css" } } - - body { margin: 0, padding: "10px", max_height: "100vh", - div { display: "flex", flex_direction: "column", max_height: "calc(100dvh - 17px)", - TopBar { players: game.read().players.clone(), port: port, stat_type: stat_type } - rsx!( - p { - padding_bottom: 0, - margin_bottom: 0, - "Game Info:" - } - figure { - overflow: "auto", - flex: "1 0 auto", - DFTable{ dataframe: game.read().summarize() } - } - p { - padding_bottom: 0, - margin_bottom: 0, - "Summary:" - } - figure { - bottom: 0, - overflow: "auto", - flex: "1 0 auto", - margin: 0, - padding: 0, - // max_height: "50vh", - DFTable{ dataframe: game.read() - .player_by_port(*port.read()) - .unwrap() - .stats - .get_summary(*stat_type.read()) - .unwrap_or_default() - } - } - if ![StatType::Input, StatType::Item].contains(&stat_type.read()) { - rsx!( - p { - padding_bottom: 0, - margin_bottom: 0, - "Events:" - } - figure { - bottom: 0, - overflow: "auto", - flex: "1 1 auto", - margin: 0, - padding: 0, - // max_height: "50vh", - DFTable{ dataframe: game.read() - .player_by_port(*port.read()) - .unwrap() - .stats - .get(*stat_type.read()) - .unwrap() - } - } - ) - } - ) - } - } - }) -} +// async fn parse_async(path: &str, multithreaded: bool) -> Vec { +// if path.is_empty() { +// return Vec::new(); +// } + +// let f_path = Path::new(path); +// if f_path.is_file() { +// return vec![Game::stub(f_path).unwrap()]; +// } +// if f_path.is_dir() { +// let files: Vec = fs::read_dir(f_path) +// .unwrap() +// .filter_map(|file| { +// if let Ok(entry) = file { +// let path = entry.path(); +// if path.is_file() && path.extension().unwrap() == "slp" { +// Some(path) +// } else { +// None +// } +// } else { +// None +// } +// }) +// .collect(); + +// let mut result: Vec = if multithreaded { +// files +// .par_iter() +// .filter_map(|path| Game::stub(path.as_path()).ok()) +// .collect() +// } else { +// files +// .iter() +// .filter_map(|path| { +// #[cfg(debug_assertions)] +// dbg!(path); + +// Game::stub(path.as_path()).ok() +// }) +// .collect() +// }; + +// // sort newest -> oldest by date +// result.sort_by(|a,b| b.cmp(a)); + +// return result; +// } +// panic!("invalid file path: {f_path:?}") +// } diff --git a/src/main.rs b/src/main.rs index ccf653d..aaaaf38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ #![allow(non_snake_case)] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] -use dioxus_desktop::{Config, WindowBuilder, tao::window::Icon}; +use dioxus_desktop::{Config, WindowBuilder, tao::{window::Icon, dpi::Size}, LogicalSize}; use dioxus_router::prelude::*; use dioxus::prelude::*; @@ -10,7 +10,7 @@ use log::LevelFilter; use polars::prelude::*; use slpprocess::parse; -use stats_dash::*; +use stats_dash::app::app; fn main() { std::env::set_var("POLARS_FMT_STR_LEN", "200"); // maximum number of characters printed per string value. @@ -24,7 +24,7 @@ fn main() { Config::new() .with_resource_directory("./dist/") .with_data_directory("./dist/") - .with_window(WindowBuilder::new().with_title("Stats Dash")) - .with_background_color((17, 25, 31, 1)) + .with_window(WindowBuilder::new().with_title("Stats Dash").with_inner_size(LogicalSize::new(1200, 700))) + .with_background_color((24, 18, 16, 1)) ); } diff --git a/src/pages/browse.rs b/src/pages/browse.rs new file mode 100644 index 0000000..20fb0ae --- /dev/null +++ b/src/pages/browse.rs @@ -0,0 +1,203 @@ +use std::{ + fs::{self, DirEntry}, + sync::Arc, time::Instant, +}; + +use dioxus::prelude::*; +use dioxus_router::prelude::*; + +use slpprocess::{parse, parse_stubs}; +use ssbm_utils::enums::{Character, Costume}; + +use crate::{ + app::{Filters, Sets, Stubs, WorkingDir}, + components::{Card, DefaultHead, StockIcon}, + utils::{get_sets, parse_entries}, static_str, +}; + +#[component] +pub fn Browse(cx: Scope) -> Element { + let working_dir = use_shared_state::(cx).unwrap(); + let stubs = use_shared_state::(cx).unwrap(); + let sets = use_shared_state::(cx).unwrap(); + let loading = use_state(cx, || false); + let progress: &UseState<(usize, usize)> = use_state(cx, || (0, 0)); + + let filters = use_ref(cx, Filters::default); + + + render!( + DefaultHead {} + body { class: "dark mask", visibility: "hidden", + nav { class: "left drawer", + header { class: "responsive", + button { + i { "folder_open" } + label { "Replay Folder" } + input { + r#type: "file", + directory: true, + onchange: |evt| { + let fs = evt.files.as_ref().unwrap().files(); + let file = fs.get(0).map(|x| x.to_owned()); + if let Some(f) = file { + if working_dir.read().0 != f && !(**loading) { + loading.set(true); + working_dir.write().0 = f.to_string(); + cx.spawn({ + to_owned!(stubs, loading, progress); + async move { + let mut files: Vec = fs::read_dir(f).unwrap().filter_map(|file| { + if let Ok(entry) = file { + let path = entry.path(); + if path.is_file() && path.extension().unwrap() == "slp" { + Some(entry) + } else { + None + } + } else { + None + } + }) + .collect(); + // sort files newest to oldest + files.sort_by_key(|a| std::cmp::Reverse(a.metadata().unwrap().created().unwrap())); + + stubs.write().0 = Vec::with_capacity(files.len()); + + progress.set((0, files.len())); + + + let paths = files.into_iter().map(|x| x.path()).collect::>(); + + + let mut now = Instant::now(); + for (i, chunk) in paths.chunks(25).enumerate() { + let c = chunk.to_vec(); + let g = tokio::spawn(async {parse_entries(c)}).await; + progress.set((i * 25, paths.len())); + // prevent fast parses groups (e.g. lots end up skipped) + // from causing stubs to be updated too quickly, which locks up + // the renderer + if now.elapsed().as_millis() > 100 { + stubs.write().0.extend(g.unwrap()); + now = Instant::now(); + } else { + stubs.write_silent().0.extend(g.unwrap()); + } + } + + // sets.write().0 = get_sets(&stubs.read().0); + + dbg!("Done"); + + loading.set(false); + + } + }) + } + } + } + } + } + } + + if !stubs.read().0.is_empty() { + render!( + div { span { "Filter" } } + + div { class: "field label border", + input { + r#type: "text", + // dumb workaround to stop the helper text from overlapping input text + placeholder: "{filters.read().code.is_empty().then_some(\"\").unwrap_or(\" \")}", + oninput: |evt| { + dbg!(evt.value.clone()); + filters.write().code = evt.value.clone()}, + } + label { color: "#999", "CODE#123"} + } + + div { class: "space" } + + div { class: "field label border", + input { + r#type: "text", + // dumb workaround to stop the helper text from overlapping input text + placeholder: "{filters.read().code.is_empty().then_some(\"\").unwrap_or(\" \")}", + oninput: |evt| { + dbg!(evt.value.clone()); + filters.write().display_name = evt.value.clone() + }, + } + label { color: "#999", "Display Name"} + } + + div { class: "space" } + // div { + // span { "Character"} + + div { class: "field suffix border", + select { + oninput: |evt| filters.write().character = Character::try_from(evt.value.as_str()).ok(), + // ordered by 2021 tier list cuz it's vaguely similar to usage chart + // and is mostly intuitive. Alternative is alphabeticle, which is + // VERY different from the usage chart albeit more intuitive. + option { "Character" } + option { static_str!(Character::Fox) } + option { static_str!(Character::Marth) } + option { static_str!(Character::Jigglypuff) } + option { static_str!(Character::Falco) } + option { static_str!(Character::Sheik) } + option { static_str!(Character::CaptainFalcon) } + option { static_str!(Character::Peach) } + option { static_str!(Character::IceClimbers) } + option { static_str!(Character::Pikachu) } + option { static_str!(Character::Yoshi) } + option { static_str!(Character::Samus) } + option { static_str!(Character::Luigi) } + option { static_str!(Character::DrMario) } + option { static_str!(Character::Ganondorf) } + option { static_str!(Character::Mario) } + option { static_str!(Character::DonkeyKong) } + option { static_str!(Character::YoungLink) } + option { static_str!(Character::Link) } + option { static_str!(Character::GameAndWatch) } + option { static_str!(Character::Mewtwo) } + option { static_str!(Character::Roy) } + option { static_str!(Character::Pichu) } + option { static_str!(Character::Ness) } + option { static_str!(Character::Zelda) } + option { static_str!(Character::Kirby) } + option { static_str!(Character::Bowser) } + } + i { "arrow_drop_down" } + } + // } + + div { class: "max" } + ) + } + } + main { class: "responsive", + if **loading { + rsx!{ + progress { + value: "{progress.0}", + max: "{progress.1}", + } + label { + "{progress.0} of {progress.1}" + } + } + } + for set in get_sets(&stubs.read().0).into_iter() { + rsx!( + Card { set: set, filters: filters.read().clone() } + + ) + } + } + } + ) +} diff --git a/src/pages/stats.rs b/src/pages/stats.rs new file mode 100644 index 0000000..36ea41b --- /dev/null +++ b/src/pages/stats.rs @@ -0,0 +1,147 @@ +use std::str::FromStr; + +use dioxus::prelude::*; +use dioxus_router::prelude::*; +use slpprocess::{stats::StatType, Game, Port}; + +use crate::{ + app::{Route, Stubs}, + components::{DFTable, DefaultHead, TopBar, StockIcon}, +}; + +#[component] +pub fn StatsPage(cx: Scope, index: usize) -> Element { + let game: Game = use_shared_state::(cx).unwrap().read().0[*index] + .clone() + .into(); + let p1 = game.players[0].clone(); + let p2 = game.players[1].clone(); + // let game = use_ref(cx, || parse(path.to_str().unwrap(), false).pop().unwrap()); + let port: &UseRef = use_ref(cx, || Port::P1); + let stat_type: &UseRef = use_ref(cx, || StatType::Defense); + let navigator = use_navigator(cx); + + render! ( + DefaultHead {} + + body { class: "dark mask", visibility: "hidden", + header { + nav { + button { class: "circle transparent", onclick: |_evt| { navigator.push(Route::Browse { });}, i { "arrow_back" }, } + div { class: "max" } + label { class: "radio max", + input { + r#type: "radio", + id: "player_1", + name: "players", + value: "p1", + checked: "true", + onclick: move |_evt| { + let mut p = port.write(); + *p = p1.port; + } + } + span {"{p1.connect_code.clone().unwrap_or(Port::P1.to_string())} "} + StockIcon { character: (p1.character, p1.costume) } + } + + label { class: "radio max", + input { + r#type: "radio", + id: "player_2", + name: "players", + value: "p2", + onclick: move |_evt| { + let mut p = port.write(); + *p = p2.port; + } + } + span {"{p2.connect_code.clone().unwrap_or(Port::P2.to_string())} "} + StockIcon { character: (p2.character, p2.costume) } + } + + div { class: "field suffix border max", + select { + name: "Stat Type", + id: "stat_type", + onchange: |evt| { + let mut st = stat_type.write(); + *st = StatType::from_str(&evt.value).unwrap(); + }, + option { value: "{StatType::Defense}", "Defense" } + option { value: "{StatType::Tech}", "Tech" } + option { value: "{StatType::Wavedash}", "Wavedash" } + option { value: "{StatType::LCancel}", "LCancel" } + option { value: "{StatType::Input}", "Input" } + option { value: "{StatType::Item}", "Item" } + } + i { "arrow_drop_down" } + } + div { class: "max" } + } + } + + main { class: "max", height: "calc(100dvh - 64px)", + div { display: "flex", flex_direction: "column", max_height: "calc(100dvh - 64px)", + p { + padding_bottom: 0, + margin_bottom: 0, + "Game Info:" + } + figure { + overflow: "auto", + flex: "1 0 auto", + DFTable{ dataframe: game.summarize() } + } + + p { + padding_bottom: 0, + margin_bottom: 0, + "Summary:" + } + div { + class: "scroll", + bottom: 0, + overflow: "auto", + flex: "1 0 auto", + margin: 0, + padding: 0, + // max_height: "50vh", + DFTable{ dataframe: game + .player_by_port(*port.read()) + .unwrap() + .stats + .get_summary(*stat_type.read()) + .unwrap_or_default() + } + } + + if ![StatType::Input, StatType::Item].contains(&stat_type.read()) { + rsx!( + p { + padding_bottom: 0, + margin_bottom: 0, + "Events:" + } + figure { + bottom: 0, + overflow: "auto", + flex: "1 1 auto", + margin: 0, + padding: 0, + // max_height: "50vh", + DFTable{ dataframe: game + .player_by_port(*port.read()) + .unwrap() + .stats + .get(*stat_type.read()) + .unwrap() + } + } + ) + } + } + } + } + ) +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..714d890 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,64 @@ +use std::{fs::DirEntry, path::PathBuf}; + +use rayon::prelude::*; +use slpprocess::{Game, GameMetadata, GameStub}; + +use crate::app::Filters; + +/// Returns a vec containin the start and end indexes (standard range format start..end) for the slices +/// containing games from a single set. +pub fn get_sets(games: &[GameStub]) -> Vec<(usize, usize)> { + if games.is_empty() { + return Vec::new(); + } + let mut result = Vec::new(); + /* probably a better way to do this, but this is what came to mind. + We essentially just check for membership via match ID and reset state any time membership + changes + */ + + // TODO handle match_id.is_none() + let mut id = games[0].match_id(); + let mut start_ind = 0; + for i in 1..games.len() { + if games[i].match_id() != id { + result.push((start_ind, i)); + start_ind = i; + id = games[i].match_id(); + } + } + + // the last set won't have a new match id to trigger its addition, so we need to manually make sure it makes it in + result.push((start_ind, games.len())); + + result +} + +pub fn parse_entries(files: Vec) -> Vec { + // dbg!(files.len()); + files + .par_iter() + .filter_map(|file| Game::stub(&file).ok()) + .collect() +} + +pub fn filter_game(game: &GameStub, filter: &Filters) -> bool { + for player in &game.players { + if (filter.character.is_none() || filter.character.is_some_and(|c| c == player.character)) + && (filter.display_name.is_empty() + || player.display_name.as_ref().is_some_and(|dn| { + dn.to_ascii_lowercase() + .starts_with(&filter.display_name.to_ascii_lowercase()) + })) + && (filter.code.is_empty() + || player.connect_code.as_ref().is_some_and(|cc| { + cc.to_ascii_lowercase() + .starts_with(&filter.code.to_ascii_lowercase()) + })) + { + return true; + } + } + + false +} diff --git a/temp.html b/temp.html new file mode 100644 index 0000000..e69de29 diff --git a/yoshis_story_pixel.png b/yoshis_story_pixel.png new file mode 100644 index 0000000..d5691ae Binary files /dev/null and b/yoshis_story_pixel.png differ