From 4c41076570073e8b960742b6e1c2231fecfa6cce Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Sat, 8 Feb 2025 21:40:01 -0800 Subject: remove rust portion as its no longer necessary --- Cargo.lock | 2094 -------------------------------------------- Cargo.toml | 9 - img/download.svg | 1 + img/globe.svg | 1 + img/layout.svg | 1 + img/plus-circle.svg | 1 + img/trash-2.svg | 1 + img/trash.svg | 1 + img/upload.svg | 1 + img/x-circle.svg | 1 + index.html | 76 ++ index.js | 659 ++++++++++++++ src/main.rs | 32 - static/img/download.svg | 1 - static/img/layout.svg | 1 - static/img/plus-circle.svg | 1 - static/img/trash-2.svg | 1 - static/img/trash.svg | 1 - static/img/upload.svg | 1 - static/img/x-circle.svg | 1 - static/index.js | 585 ------------- static/styles.css | 329 ------- styles.css | 329 +++++++ templates/index.html | 70 -- tiers.css | 195 +++++ tiers.html | 32 + tiers.js | 137 +++ 27 files changed, 1436 insertions(+), 3126 deletions(-) delete mode 100644 Cargo.lock delete mode 100644 Cargo.toml create mode 100644 img/download.svg create mode 100644 img/globe.svg create mode 100644 img/layout.svg create mode 100644 img/plus-circle.svg create mode 100644 img/trash-2.svg create mode 100644 img/trash.svg create mode 100644 img/upload.svg create mode 100644 img/x-circle.svg create mode 100644 index.html create mode 100644 index.js delete mode 100644 src/main.rs delete mode 100644 static/img/download.svg delete mode 100644 static/img/layout.svg delete mode 100644 static/img/plus-circle.svg delete mode 100644 static/img/trash-2.svg delete mode 100644 static/img/trash.svg delete mode 100644 static/img/upload.svg delete mode 100644 static/img/x-circle.svg delete mode 100644 static/index.js delete mode 100644 static/styles.css create mode 100644 styles.css delete mode 100644 templates/index.html create mode 100644 tiers.css create mode 100644 tiers.html create mode 100644 tiers.js diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index bbd1f27..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,2094 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "actix-codec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-sink", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-files" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0773d59061dedb49a8aed04c67291b9d8cf2fe0b60130a381aab53c6dd86e9be" -dependencies = [ - "actix-http", - "actix-service", - "actix-utils", - "actix-web", - "bitflags", - "bytes", - "derive_more", - "futures-core", - "http-range", - "log", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite", - "v_htmlescape", -] - -[[package]] -name = "actix-http" -version = "3.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "ahash", - "base64", - "bitflags", - "brotli", - "bytes", - "bytestring", - "derive_more", - "encoding_rs", - "flate2", - "futures-core", - "h2", - "http", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "mime", - "percent-encoding", - "pin-project-lite", - "rand", - "sha1", - "smallvec", - "tokio", - "tokio-util", - "tracing", - "zstd", -] - -[[package]] -name = "actix-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "actix-router" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" -dependencies = [ - "bytestring", - "cfg-if", - "http", - "regex", - "regex-lite", - "serde", - "tracing", -] - -[[package]] -name = "actix-rt" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" -dependencies = [ - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca2549781d8dd6d75c40cf6b6051260a2cc2f3c62343d761a969a0640646894" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "mio", - "socket2", - "tokio", - "tracing", -] - -[[package]] -name = "actix-service" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" -dependencies = [ - "futures-core", - "paste", - "pin-project-lite", -] - -[[package]] -name = "actix-utils" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" -dependencies = [ - "local-waker", - "pin-project-lite", -] - -[[package]] -name = "actix-web" -version = "4.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "ahash", - "bytes", - "bytestring", - "cfg-if", - "cookie", - "derive_more", - "encoding_rs", - "futures-core", - "futures-util", - "impl-more", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "pin-project-lite", - "regex", - "regex-lite", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2", - "time", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "getrandom", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bitflags" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "brotli" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "4.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bstr" -version = "1.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" - -[[package]] -name = "bytestring" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e465647ae23b2823b0753f50decb2d5a86d2bb2cac04788fafd1f80e45378e5f" -dependencies = [ - "bytes", -] - -[[package]] -name = "cc" -version = "1.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755717a7de9ec452bf7f3f1a3099085deabd7f2962b861dae91ecd7a365903d2" -dependencies = [ - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "windows-targets", -] - -[[package]] -name = "chrono-tz" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" -dependencies = [ - "chrono", - "chrono-tz-build", - "phf", -] - -[[package]] -name = "chrono-tz-build" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" -dependencies = [ - "parse-zoneinfo", - "phf", - "phf_codegen", -] - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derive_more" -version = "0.99.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn", -] - -[[package]] -name = "deunicode" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00" - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "flate2" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "globset" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "globwalk" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" -dependencies = [ - "bitflags", - "ignore", - "walkdir", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-range" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" - -[[package]] -name = "httparse" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humansize" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" -dependencies = [ - "libm", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - -[[package]] -name = "icu_normalizer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" - -[[package]] -name = "icu_properties" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" - -[[package]] -name = "icu_provider" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "ignore" -version = "0.4.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata", - "same-file", - "walkdir", - "winapi-util", -] - -[[package]] -name = "impl-more" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" - -[[package]] -name = "indexmap" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "itoa" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" - -[[package]] -name = "jobserver" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.169" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" - -[[package]] -name = "libm" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" - -[[package]] -name = "litemap" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" - -[[package]] -name = "local-channel" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" -dependencies = [ - "futures-core", - "futures-sink", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "parse-zoneinfo" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" -dependencies = [ - "regex", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pest_meta" -version = "2.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" -dependencies = [ - "once_cell", - "pest", - "sha2", -] - -[[package]] -name = "phf" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_shared", -] - -[[package]] -name = "phf_codegen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" -dependencies = [ - "phf_generator", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared", - "rand", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "redox_syscall" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-lite" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "rust_boilerplate" -version = "0.1.0" -dependencies = [ - "actix-files", - "actix-web", - "tera", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustversion" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" - -[[package]] -name = "ryu" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "semver" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" - -[[package]] -name = "serde" -version = "1.0.217" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.217" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.138" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "slug" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724" -dependencies = [ - "deunicode", - "wasm-bindgen", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "syn" -version = "2.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tera" -version = "1.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab9d851b45e865f178319da0abdbfe6acbc4328759ff18dafc3a41c16b4cd2ee" -dependencies = [ - "chrono", - "chrono-tz", - "globwalk", - "humansize", - "lazy_static", - "percent-encoding", - "pest", - "pest_derive", - "rand", - "regex", - "serde", - "serde_json", - "slug", - "unic-segment", -] - -[[package]] -name = "thiserror" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.3.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tokio" -version = "1.43.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-util" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "log", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" -dependencies = [ - "once_cell", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "ucd-trie" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" - -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" -dependencies = [ - "unic-ucd-segment", -] - -[[package]] -name = "unic-ucd-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - -[[package]] -name = "unicase" -version = "2.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" - -[[package]] -name = "unicode-ident" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" - -[[package]] -name = "url" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "v_htmlescape" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - -[[package]] -name = "writeable" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" - -[[package]] -name = "yoke" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerovec" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zstd" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 3cb6c9f..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "rust_boilerplate" -version = "0.1.0" -edition = "2021" - -[dependencies] -actix-web = "4" -tera = "1.17.0" -actix-files = "0.6" diff --git a/img/download.svg b/img/download.svg new file mode 100644 index 0000000..ffa0e9a --- /dev/null +++ b/img/download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/globe.svg b/img/globe.svg new file mode 100644 index 0000000..5835fd6 --- /dev/null +++ b/img/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/layout.svg b/img/layout.svg new file mode 100644 index 0000000..1943229 --- /dev/null +++ b/img/layout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/plus-circle.svg b/img/plus-circle.svg new file mode 100644 index 0000000..015bb62 --- /dev/null +++ b/img/plus-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/trash-2.svg b/img/trash-2.svg new file mode 100644 index 0000000..ce3947d --- /dev/null +++ b/img/trash-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/trash.svg b/img/trash.svg new file mode 100644 index 0000000..38e9c35 --- /dev/null +++ b/img/trash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/upload.svg b/img/upload.svg new file mode 100644 index 0000000..e09b69f --- /dev/null +++ b/img/upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/x-circle.svg b/img/x-circle.svg new file mode 100644 index 0000000..433837f --- /dev/null +++ b/img/x-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..fa499e6 --- /dev/null +++ b/index.html @@ -0,0 +1,76 @@ + + + + + Interactive Tiers + + + + +
+ + +
+ GitHub +
+
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+

Hint: you can paste an image into this page to have it show up in the image list.

+
+
+
+ +
+ + +
+
+ + + \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..366a0b5 --- /dev/null +++ b/index.js @@ -0,0 +1,659 @@ +/* + Offline Tierlist Maker + Copyright (C) 2022 silverweed + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. +*/ + +'use strict'; + +const MAX_NAME_LEN = 200; +const DEFAULT_TIERS = ['S', 'A', 'B', 'C', 'D', 'E', 'F']; +const TIER_COLORS = [ + '#ff6666', + '#f0a731', + '#f4d95b', + '#66ff66', + '#58c8f4', + '#5b76f4', + '#f45bed' +]; + +let unique_id = 0; + +let unsaved_changes = false; + +const LAYOUT_HORIZONTAL = 0; +const LAYOUT_VERTICAL = 1; +let cur_layout = LAYOUT_HORIZONTAL; + +// Contains [[header, input, label]] +let all_headers = []; +let headers_orig_min_width; + +// DOM elems +let untiered_images; +let tierlist_div; +let dragged_image; + +function reset_row(row) { + row.querySelectorAll('span.item').forEach((item) => { + for (let i = 0; i < item.children.length; ++i) { + let img = item.children[i]; + item.removeChild(img); + untiered_images.appendChild(img); + } + item.parentNode.removeChild(item); + }); +} + +function hard_reset_list() { + tierlist_div.innerHTML = ''; + untiered_images.innerHTML = ''; +} + +function soft_reset_list() { + tierlist_div.querySelectorAll('.row').forEach(reset_row); + unsaved_changes = true; +} + +window.addEventListener('load', () => { + untiered_images = document.querySelector('.images'); + tierlist_div = document.querySelector('.tierlist'); + + for (let i = 0; i < DEFAULT_TIERS.length; ++i) { + add_row(i, DEFAULT_TIERS[i]); + } + recompute_header_colors(); + + headers_orig_min_width = all_headers[0][0].clientWidth; + + make_accept_drop(document.querySelector('.images')); + + bind_title_events(); + + document.getElementById('load-img-input').addEventListener('input', (evt) => { + let images = document.querySelector('.images'); + for (let file of evt.target.files) { + let reader = new FileReader(); + reader.addEventListener('load', (load_evt) => { + let img = create_img_with_src(load_evt.target.result); + images.appendChild(img); + unsaved_changes = true; + }); + reader.readAsDataURL(file); + } + }); + + document.onpaste = (evt) => { + let clip_data = evt.clipboardData || evt.originalEvent.clipboardData; + let items = clip_data.items; + let images = document.querySelector('.images'); + for (let item of items) { + if (item.kind === 'file') { + let blob = item.getAsFile(); + let reader = new FileReader(); + reader.onload = (load_evt) => { + let img = create_img_with_src(load_evt.target.result); + images.appendChild(img); + unsaved_changes = true; + }; + reader.readAsDataURL(blob); + } + } + }; + + document.getElementById('reset-list-input').addEventListener('click', () => { + if (confirm('Reset Tierlist? (this will place all images back in the pool)')) { + soft_reset_list(); + } + }); + + document.getElementById('export-input').addEventListener('click', () => { + let name = prompt('Please give a name to the file. This will export your tiers as a JSON file so you can continue working on it later'); + if (name) { + save_tierlist(`${name}.json`); + } + }); + + document.getElementById('export-input-html').addEventListener('click', () => { + let name = prompt('This will export your tiers as a single interactive HTML file. Please give a name to the file'); + if (name) { + save_tierlist_with_template(`${name}.html`); + } + }); + + document.getElementById('import-input').addEventListener('input', (evt) => { + if (!evt.target.files) { + return; + } + let file = evt.target.files[0]; + let reader = new FileReader(); + reader.addEventListener('load', (load_evt) => { + let raw = load_evt.target.result; + let parsed = JSON.parse(raw); + if (!parsed) { + alert("Failed to parse data"); + return; + } + hard_reset_list(); + load_tierlist(parsed); + }); + reader.readAsText(file); + }); + + bind_trash_events(); + bind_toggle_layout_events(); + + window.addEventListener('beforeunload', (evt) => { + if (!unsaved_changes) return null; + var msg = "You have unsaved changes. Leave anyway?"; + (evt || window.event).returnValue = msg; + return msg; + }); + + void try_load_tierlist_json(); + + const modal = document.getElementById('image-modal'); + const modalImg = document.getElementById('modal-img'); + const modalTitle = document.getElementById('modal-title'); + const modalDesc = document.getElementById('modal-description'); + const modalSave = document.getElementById('modal-save'); + const modalClose = document.querySelector('.modal .close'); + let currentModalImage = null; + + function showModal(img) { + currentModalImage = img; + document.body.style.overflow = 'hidden'; + modal.style.display = 'flex'; + modalImg.src = img.src; + modalTitle.value = img.dataset.title || ''; + modalDesc.value = img.dataset.description || ''; + } + + modalClose.addEventListener('click', () => { + modal.style.display = 'none'; + document.body.style.overflow = 'hidden'; + }); + + modalSave.addEventListener('click', () => { + if (currentModalImage) { + currentModalImage.dataset.title = modalTitle.value; + currentModalImage.dataset.description = modalDesc.value; + } + modal.style.display = 'none'; + document.body.style.overflow = 'hidden'; + }); + + window.addEventListener('click', (evt) => { + if (evt.target == modal) { + modal.style.display = 'none'; + document.body.style.overflow = 'hidden'; + } + }); + + tierlist_div.addEventListener('click', (evt) => { + if (evt.target.tagName.toUpperCase() === 'IMG') { + showModal(evt.target); + } + }); +}); + +function create_img_with_src(src) { + let img = document.createElement('img'); + img.src = src; + img.style.userSelect = 'none'; + img.classList.add('draggable'); + img.draggable = true; + + img.addEventListener("dragstart", (evt) => { + evt.dataTransfer.setData("text/plain", null); + dragged_image = evt.target; + dragged_image.classList.add("dragged"); + }); + + img.addEventListener("mouseenter", (evt) => { + const title = evt.target.dataset.title; + if (title) { + evt.target.title = title; + } + }); + + img.addEventListener("dragend", (evt) => { + if (dragged_image) { + dragged_image.classList.remove("dragged"); + } + dragged_image = null; + }); + + return img; +} + + +function save(filename, text) { + unsaved_changes = false; + + var el = document.createElement('a'); + el.setAttribute('href', 'data:text/html;charset=utf-8,' + encodeURIComponent(text)); + el.setAttribute('download', filename); + el.style.display = 'none'; + document.body.appendChild(el); + el.click(); + document.body.removeChild(el); +} + +function save_tierlist(filename) { + let serialized_tierlist = { + title: document.querySelector('.title-label').innerText, + rows: [], + }; + tierlist_div.querySelectorAll('.row').forEach((row, i) => { + serialized_tierlist.rows.push({ + name: row.querySelector('.header label').innerText.substr(0, MAX_NAME_LEN) + }); + serialized_tierlist.rows[i].imgs = []; + row.querySelectorAll('img').forEach((img) => { + serialized_tierlist.rows[i].imgs.push({ + src: img.src, + title: img.dataset.title || '', + description: img.dataset.description || '' + }); + }); + }); + + let untiered_imgs = document.querySelectorAll('.images img'); + if (untiered_imgs.length > 0) { + serialized_tierlist.untiered = []; + untiered_imgs.forEach((img) => { + serialized_tierlist.untiered.push({ + src: img.src, + title: img.dataset.title || '', + description: img.dataset.description || '' + }); + }); + } + + save(filename, JSON.stringify(serialized_tierlist)); +} +async function save_tierlist_with_template(filename) { + let serialized_tierlist = { + title: document.querySelector('.title-label').innerText, + rows: [] + }; + + tierlist_div.querySelectorAll('.row').forEach((row, i) => { + serialized_tierlist.rows.push({ + name: row.querySelector('.header').innerText.substr(0, MAX_NAME_LEN) + }); + serialized_tierlist.rows[i].imgs = []; + row.querySelectorAll('img').forEach((img) => { + serialized_tierlist.rows[i].imgs.push({ + src: img.src, + title: img.dataset.title || '', + description: img.dataset.description || '' + }); + }); + }); + + let untiered_imgs = document.querySelectorAll('.images img'); + if (untiered_imgs.length > 0) { + serialized_tierlist.untiered = []; + untiered_imgs.forEach((img) => { + serialized_tierlist.untiered.push({ + src: img.src, + title: img.dataset.title || '', + description: img.dataset.description || '' + }); + }); + } + + try { + // Fetch resources + let [templateResponse, jsResponse, cssResponse] = await Promise.all([ + fetch('/tiers'), + fetch('/tiers.js'), + fetch('/tiers.css') + ]); + + let [templateHTML, scriptContent, styleContent] = await Promise.all([ + templateResponse.text(), + jsResponse.text(), + cssResponse.text() + ]); + + // Inject the EMBEDDED_JSON inside a script tag + let jsonScript = ``; + + let inlineScript = ``; + let inlineCSS = ``; + + templateHTML = templateHTML.replace("", inlineCSS + "\n"); + let updatedHTML = templateHTML.replace("", jsonScript + "\n" + inlineScript + "\n"); + save(filename, updatedHTML); + } catch (e) { + console.error("Error fetching resources:", e); + } +} + + + +function load_tierlist(serialized_tierlist) { + document.querySelector('.title-label').innerText = serialized_tierlist.title; + for (let idx in serialized_tierlist.rows) { + let ser_row = serialized_tierlist.rows[idx]; + let elem = add_row(idx, ser_row.name); + + for (let img_obj of ser_row.imgs ?? []) { + let img = create_img_with_src(img_obj.src); + img.dataset.title = img_obj.title || ''; + img.dataset.description = img_obj.description || ''; + let td = document.createElement('span'); + td.classList.add('item'); + td.appendChild(img); + let items_container = elem.querySelector('.items'); + items_container.appendChild(td); + } + + elem.querySelector('label').innerText = ser_row.name; + } + recompute_header_colors(); + + if (serialized_tierlist.untiered) { + let images = document.querySelector('.images'); + for (let img_obj of serialized_tierlist.untiered) { + let img = create_img_with_src(img_obj.src); + img.dataset.title = img_obj.title || ''; + img.dataset.description = img_obj.description || ''; + images.appendChild(img); + } + } + + resize_headers(); + + unsaved_changes = false; +} + +function end_drag(evt) { + if (dragged_image) { + dragged_image.classList.remove("dragged"); + } + dragged_image = null; +} + +window.addEventListener('mouseup', end_drag); +window.addEventListener('dragend', end_drag); + + +function make_accept_drop(elem) { + elem.classList.add('droppable'); + + elem.addEventListener('dragenter', (evt) => { + evt.preventDefault(); + evt.target.classList.add('drag-entered'); + }); + + elem.addEventListener('dragleave', (evt) => { + evt.target.classList.remove('drag-entered'); + }); + + elem.addEventListener('dragover', (evt) => { + evt.preventDefault(); + }); + + elem.addEventListener('drop', (evt) => { + evt.preventDefault(); + evt.target.classList.remove('drag-entered'); + + if (!dragged_image) { + return; + } + + let dragged_image_parent = dragged_image.parentNode; + if (dragged_image_parent.tagName.toUpperCase() === 'SPAN' && + dragged_image_parent.classList.contains('item')) { + let containing_tr = dragged_image_parent.parentNode; + containing_tr.removeChild(dragged_image_parent); + } else { + dragged_image_parent.removeChild(dragged_image); + } + + let td = document.createElement('span'); + td.classList.add('item'); + td.appendChild(dragged_image); + let items_container = elem.querySelector('.items'); + + if (!items_container) { + items_container = elem; + } + items_container.appendChild(td); + + dragged_image.draggable = true; + dragged_image.classList.remove("dragged"); + + dragged_image.addEventListener("dragstart", (e) => { + e.dataTransfer.setData("text/plain", null); + dragged_image.classList.add("dragged"); + }); + + unsaved_changes = true; + }); +} + + +function enable_edit_on_click(container, input, label) { + function change_label(evt) { + input.style.display = 'none'; + label.innerText = input.value; + label.style.display = 'inline'; + unsaved_changes = true; + } + + input.addEventListener('change', change_label); + input.addEventListener('focusout', change_label); + + container.addEventListener('click', (evt) => { + label.style.display = 'none'; + input.value = label.innerText.substr(0, MAX_NAME_LEN); + input.style.display = 'inline'; + input.select(); + }); +} + +function bind_title_events() { + let title_label = document.querySelector('.title-label'); + let title_input = document.getElementById('title-input'); + let title = document.querySelector('.title'); + + enable_edit_on_click(title, title_input, title_label); +} + +function create_label_input(row, row_idx, row_name) { + let input = document.createElement('input'); + input.id = `input-tier-${unique_id++}`; + input.type = 'text'; + input.addEventListener('change', resize_headers); + let label = document.createElement('label'); + label.htmlFor = input.id; + label.innerText = row_name; + + let header = row.querySelector('.header'); + all_headers.splice(row_idx, 0, [header, input, label]); + header.appendChild(label); + header.appendChild(input); + + enable_edit_on_click(header, input, label); +} + +function resize_headers() { + let max_width = headers_orig_min_width; + for (let [other_header, _i, label] of all_headers) { + max_width = Math.max(max_width, label.clientWidth); + } + + for (let [other_header, _i2, _l2] of all_headers) { + other_header.style.minWidth = `${max_width}px`; + } +} + +function add_row(index, name) { + let div = document.createElement('div'); + let header = document.createElement('span'); + let items = document.createElement('span'); + div.classList.add('row'); + header.classList.add('header'); + items.classList.add('items'); + div.appendChild(header); + div.appendChild(items); + let row_buttons = document.createElement('div'); + row_buttons.classList.add('row-buttons'); + let btn_plus_up = document.createElement('input'); + btn_plus_up.type = "button"; + btn_plus_up.value = '+'; + btn_plus_up.title = "Add row above"; + btn_plus_up.addEventListener('click', (evt) => { + let parent_div = evt.target.parentNode.parentNode; + let rows = Array.from(tierlist_div.children); + let idx = rows.indexOf(parent_div); + console.assert(idx >= 0); + add_row(idx, ''); + recompute_header_colors(); + }); + let btn_rm = document.createElement('input'); + btn_rm.type = "button"; + btn_rm.value = '-'; + btn_rm.title = "Remove row"; + btn_rm.addEventListener('click', (evt) => { + let rows = Array.from(tierlist_div.querySelectorAll('.row')); + if (rows.length < 2) return; + let parent_div = evt.target.parentNode.parentNode; + let idx = rows.indexOf(parent_div); + console.assert(idx >= 0); + if (rows[idx].querySelectorAll('img').length === 0 || + confirm(`Remove tier ${rows[idx].querySelector('.header label').innerText}? (This will move back all its content to the untiered pool)`)) { + rm_row(idx); + } + recompute_header_colors(); + }); + let btn_plus_down = document.createElement('input'); + btn_plus_down.type = "button"; + btn_plus_down.value = '+'; + btn_plus_down.title = "Add row below"; + btn_plus_down.addEventListener('click', (evt) => { + let parent_div = evt.target.parentNode.parentNode; + let rows = Array.from(tierlist_div.children); + let idx = rows.indexOf(parent_div); + console.assert(idx >= 0); + add_row(idx + 1, name); + recompute_header_colors(); + }); + row_buttons.appendChild(btn_plus_up); + row_buttons.appendChild(btn_rm); + row_buttons.appendChild(btn_plus_down); + div.appendChild(row_buttons); + + let rows = tierlist_div.children; + if (index === rows.length) { + tierlist_div.appendChild(div); + } else { + let nxt_child = rows[index]; + tierlist_div.insertBefore(div, nxt_child); + } + + make_accept_drop(div); + create_label_input(div, index, name); + + return div; +} + +function rm_row(idx) { + let row = tierlist_div.children[idx]; + reset_row(row); + tierlist_div.removeChild(row); +} + +function recompute_header_colors() { + tierlist_div.querySelectorAll('.row').forEach((row, row_idx) => { + let color = TIER_COLORS[row_idx % TIER_COLORS.length]; + row.querySelector('.header').style.backgroundColor = color; + }); +} + +function bind_trash_events() { + let trash = document.getElementById('trash'); + trash.classList.add('droppable'); + trash.addEventListener('dragenter', (evt) => { + evt.preventDefault(); + evt.target.src = '/img/trash-2.svg'; + }); + trash.addEventListener('dragexit', (evt) => { + evt.preventDefault(); + evt.target.src = '/img/trash.svg'; + }); + trash.addEventListener('dragover', (evt) => { + evt.preventDefault(); + }); + trash.addEventListener('drop', (evt) => { + evt.preventDefault(); + evt.target.src = '/img/trash.svg'; + if (dragged_image) { + let dragged_image_parent = dragged_image.parentNode; + if (dragged_image_parent.tagName.toUpperCase() === 'SPAN' && + dragged_image_parent.classList.contains('item')) { + let containing_tr = dragged_image_parent.parentNode; + containing_tr.removeChild(dragged_image_parent); + } + dragged_image.remove(); + } + }); +} + +function bind_toggle_layout_events() { + let toggle = document.getElementById('toggle-layout'); + toggle.addEventListener('click', () => { + set_layout((cur_layout + 1) % 2); + }); +} + +function set_layout(layout) { + let main = document.getElementsByClassName("main-content")[0]; + if (layout === LAYOUT_VERTICAL) { + main.classList.add("vertical"); + } else { + main.classList.remove("vertical"); + } + cur_layout = layout; +} + +function is_url(str) { + try { + new URL(str); + return true; + } catch (e) { + return false; + } +} + +async function try_load_tierlist_json() { + const load_from_url = new URLSearchParams(window.location.search).get('url'); + if (load_from_url !== null && is_url(load_from_url)) { + try { + let result = await fetch(load_from_url); + result = await result.json(); + hard_reset_list(); + load_tierlist(result); + } catch (e) { console.error(e); } + } +} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 877b86d..0000000 --- a/src/main.rs +++ /dev/null @@ -1,32 +0,0 @@ -use actix_files as fs; -use actix_web::{web, App, HttpResponse, HttpServer, Result}; -use tera::Tera; - -async fn index(templates: web::Data) -> Result { - let mut context = tera::Context::new(); - context.insert("name", "World"); - - let rendered = templates - .render("index.html", &context) - .map_err(|e| { - eprintln!("Template rendering error: {}", e); - actix_web::error::ErrorInternalServerError("Template rendering error") - })?; - - Ok(HttpResponse::Ok().content_type("text/html").body(rendered)) -} - -#[actix_web::main] -async fn main() -> std::io::Result<()> { - let tera = Tera::new("templates/**/*").expect("Error initializing Tera"); - - HttpServer::new(move || { - App::new() - .app_data(web::Data::new(tera.clone())) - .route("/", web::get().to(index)) - .service(fs::Files::new("/static", "./static").show_files_listing()) - }) - .bind("127.0.0.1:8080")? - .run() - .await -} diff --git a/static/img/download.svg b/static/img/download.svg deleted file mode 100644 index ffa0e9a..0000000 --- a/static/img/download.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/static/img/layout.svg b/static/img/layout.svg deleted file mode 100644 index 1943229..0000000 --- a/static/img/layout.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/static/img/plus-circle.svg b/static/img/plus-circle.svg deleted file mode 100644 index 015bb62..0000000 --- a/static/img/plus-circle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/static/img/trash-2.svg b/static/img/trash-2.svg deleted file mode 100644 index ce3947d..0000000 --- a/static/img/trash-2.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/static/img/trash.svg b/static/img/trash.svg deleted file mode 100644 index 38e9c35..0000000 --- a/static/img/trash.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/static/img/upload.svg b/static/img/upload.svg deleted file mode 100644 index e09b69f..0000000 --- a/static/img/upload.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/static/img/x-circle.svg b/static/img/x-circle.svg deleted file mode 100644 index 433837f..0000000 --- a/static/img/x-circle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/static/index.js b/static/index.js deleted file mode 100644 index ffc5532..0000000 --- a/static/index.js +++ /dev/null @@ -1,585 +0,0 @@ -/* - Offline Tierlist Maker - Copyright (C) 2022 silverweed - - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. -*/ - -'use strict'; - -const MAX_NAME_LEN = 200; -const DEFAULT_TIERS = ['S', 'A', 'B', 'C', 'D', 'E', 'F']; -const TIER_COLORS = [ - '#ff6666', - '#f0a731', - '#f4d95b', - '#66ff66', - '#58c8f4', - '#5b76f4', - '#f45bed' -]; - -let unique_id = 0; - -let unsaved_changes = false; - -const LAYOUT_HORIZONTAL = 0; -const LAYOUT_VERTICAL = 1; -let cur_layout = LAYOUT_HORIZONTAL; - -// Contains [[header, input, label]] -let all_headers = []; -let headers_orig_min_width; - -// DOM elems -let untiered_images; -let tierlist_div; -let dragged_image; - -function reset_row(row) { - row.querySelectorAll('span.item').forEach((item) => { - for (let i = 0; i < item.children.length; ++i) { - let img = item.children[i]; - item.removeChild(img); - untiered_images.appendChild(img); - } - item.parentNode.removeChild(item); - }); -} - -function hard_reset_list() { - tierlist_div.innerHTML = ''; - untiered_images.innerHTML = ''; -} - -function soft_reset_list() { - tierlist_div.querySelectorAll('.row').forEach(reset_row); - unsaved_changes = true; -} - -window.addEventListener('load', () => { - untiered_images = document.querySelector('.images'); - tierlist_div = document.querySelector('.tierlist'); - - for (let i = 0; i < DEFAULT_TIERS.length; ++i) { - add_row(i, DEFAULT_TIERS[i]); - } - recompute_header_colors(); - - headers_orig_min_width = all_headers[0][0].clientWidth; - - make_accept_drop(document.querySelector('.images')); - - bind_title_events(); - - document.getElementById('load-img-input').addEventListener('input', (evt) => { - let images = document.querySelector('.images'); - for (let file of evt.target.files) { - let reader = new FileReader(); - reader.addEventListener('load', (load_evt) => { - let img = create_img_with_src(load_evt.target.result); - images.appendChild(img); - unsaved_changes = true; - }); - reader.readAsDataURL(file); - } - }); - - document.onpaste = (evt) => { - let clip_data = evt.clipboardData || evt.originalEvent.clipboardData; - let items = clip_data.items; - let images = document.querySelector('.images'); - for (let item of items) { - if (item.kind === 'file') { - let blob = item.getAsFile(); - let reader = new FileReader(); - reader.onload = (load_evt) => { - let img = create_img_with_src(load_evt.target.result); - images.appendChild(img); - unsaved_changes = true; - }; - reader.readAsDataURL(blob); - } - } - }; - - document.getElementById('reset-list-input').addEventListener('click', () => { - if (confirm('Reset Tierlist? (this will place all images back in the pool)')) { - soft_reset_list(); - } - }); - - document.getElementById('export-input').addEventListener('click', () => { - let name = prompt('Please give a name to this tierlist'); - if (name) { - save_tierlist(`${name}.json`); - } - }); - - document.getElementById('import-input').addEventListener('input', (evt) => { - if (!evt.target.files) { - return; - } - let file = evt.target.files[0]; - let reader = new FileReader(); - reader.addEventListener('load', (load_evt) => { - let raw = load_evt.target.result; - let parsed = JSON.parse(raw); - if (!parsed) { - alert("Failed to parse data"); - return; - } - hard_reset_list(); - load_tierlist(parsed); - }); - reader.readAsText(file); - }); - - bind_trash_events(); - bind_toggle_layout_events(); - - window.addEventListener('beforeunload', (evt) => { - if (!unsaved_changes) return null; - var msg = "You have unsaved changes. Leave anyway?"; - (evt || window.event).returnValue = msg; - return msg; - }); - - void try_load_tierlist_json(); - - const modal = document.getElementById('image-modal'); - const modalImg = document.getElementById('modal-img'); - const modalTitle = document.getElementById('modal-title'); - const modalDesc = document.getElementById('modal-description'); - const modalSave = document.getElementById('modal-save'); - const modalClose = document.querySelector('.modal .close'); - let currentModalImage = null; - - function showModal(img) { - currentModalImage = img; - document.body.style.overflow = 'hidden'; - modal.style.display = 'flex'; - modalImg.src = img.src; - modalTitle.value = img.dataset.title || ''; - modalDesc.value = img.dataset.description || ''; - } - - modalClose.addEventListener('click', () => { - modal.style.display = 'none'; - document.body.style.overflow = 'hidden'; - }); - - modalSave.addEventListener('click', () => { - if (currentModalImage) { - currentModalImage.dataset.title = modalTitle.value; - currentModalImage.dataset.description = modalDesc.value; - } - modal.style.display = 'none'; - document.body.style.overflow = 'hidden'; - }); - - window.addEventListener('click', (evt) => { - if (evt.target == modal) { - modal.style.display = 'none'; - document.body.style.overflow = 'hidden'; - } - }); - - tierlist_div.addEventListener('click', (evt) => { - if (evt.target.tagName.toUpperCase() === 'IMG') { - showModal(evt.target); - } - }); -}); - -function create_img_with_src(src) { - let img = document.createElement('img'); - img.src = src; - img.style.userSelect = 'none'; - img.classList.add('draggable'); - img.draggable = true; - - img.addEventListener("dragstart", (evt) => { - evt.dataTransfer.setData("text/plain", null); - dragged_image = evt.target; - dragged_image.classList.add("dragged"); - }); - - img.addEventListener("mouseenter", (evt) => { - const title = evt.target.dataset.title; - if (title) { - evt.target.title = title; - } - }); - - img.addEventListener("dragend", (evt) => { - if (dragged_image) { - dragged_image.classList.remove("dragged"); - } - dragged_image = null; - }); - - return img; -} - - -function save(filename, text) { - unsaved_changes = false; - - var el = document.createElement('a'); - el.setAttribute('href', 'data:text/html;charset=utf-8,' + encodeURIComponent(text)); - el.setAttribute('download', filename); - el.style.display = 'none'; - document.body.appendChild(el); - el.click(); - document.body.removeChild(el); -} - -function save_tierlist(filename) { - let serialized_tierlist = { - title: document.querySelector('.title-label').innerText, - rows: [], - }; - tierlist_div.querySelectorAll('.row').forEach((row, i) => { - serialized_tierlist.rows.push({ - name: row.querySelector('.header label').innerText.substr(0, MAX_NAME_LEN) - }); - serialized_tierlist.rows[i].imgs = []; - row.querySelectorAll('img').forEach((img) => { - serialized_tierlist.rows[i].imgs.push({ - src: img.src, - title: img.dataset.title || '', - description: img.dataset.description || '' - }); - }); - }); - - let untiered_imgs = document.querySelectorAll('.images img'); - if (untiered_imgs.length > 0) { - serialized_tierlist.untiered = []; - untiered_imgs.forEach((img) => { - serialized_tierlist.untiered.push({ - src: img.src, - title: img.dataset.title || '', - description: img.dataset.description || '' - }); - }); - } - - save(filename, JSON.stringify(serialized_tierlist)); -} - -function load_tierlist(serialized_tierlist) { - document.querySelector('.title-label').innerText = serialized_tierlist.title; - for (let idx in serialized_tierlist.rows) { - let ser_row = serialized_tierlist.rows[idx]; - let elem = add_row(idx, ser_row.name); - - for (let img_obj of ser_row.imgs ?? []) { - let img = create_img_with_src(img_obj.src); - img.dataset.title = img_obj.title || ''; - img.dataset.description = img_obj.description || ''; - let td = document.createElement('span'); - td.classList.add('item'); - td.appendChild(img); - let items_container = elem.querySelector('.items'); - items_container.appendChild(td); - } - - elem.querySelector('label').innerText = ser_row.name; - } - recompute_header_colors(); - - if (serialized_tierlist.untiered) { - let images = document.querySelector('.images'); - for (let img_obj of serialized_tierlist.untiered) { - let img = create_img_with_src(img_obj.src); - img.dataset.title = img_obj.title || ''; - img.dataset.description = img_obj.description || ''; - images.appendChild(img); - } - } - - resize_headers(); - - unsaved_changes = false; -} - -function end_drag(evt) { - if (dragged_image) { - dragged_image.classList.remove("dragged"); - } - dragged_image = null; -} - -window.addEventListener('mouseup', end_drag); -window.addEventListener('dragend', end_drag); - - -function make_accept_drop(elem) { - elem.classList.add('droppable'); - - elem.addEventListener('dragenter', (evt) => { - evt.preventDefault(); - evt.target.classList.add('drag-entered'); - }); - - elem.addEventListener('dragleave', (evt) => { - evt.target.classList.remove('drag-entered'); - }); - - elem.addEventListener('dragover', (evt) => { - evt.preventDefault(); - }); - - elem.addEventListener('drop', (evt) => { - evt.preventDefault(); - evt.target.classList.remove('drag-entered'); - - if (!dragged_image) { - return; - } - - let dragged_image_parent = dragged_image.parentNode; - if (dragged_image_parent.tagName.toUpperCase() === 'SPAN' && - dragged_image_parent.classList.contains('item')) { - let containing_tr = dragged_image_parent.parentNode; - containing_tr.removeChild(dragged_image_parent); - } else { - dragged_image_parent.removeChild(dragged_image); - } - - let td = document.createElement('span'); - td.classList.add('item'); - td.appendChild(dragged_image); - let items_container = elem.querySelector('.items'); - - if (!items_container) { - items_container = elem; - } - items_container.appendChild(td); - - dragged_image.draggable = true; - dragged_image.classList.remove("dragged"); - - dragged_image.addEventListener("dragstart", (e) => { - e.dataTransfer.setData("text/plain", null); - dragged_image.classList.add("dragged"); - }); - - unsaved_changes = true; - }); -} - - -function enable_edit_on_click(container, input, label) { - function change_label(evt) { - input.style.display = 'none'; - label.innerText = input.value; - label.style.display = 'inline'; - unsaved_changes = true; - } - - input.addEventListener('change', change_label); - input.addEventListener('focusout', change_label); - - container.addEventListener('click', (evt) => { - label.style.display = 'none'; - input.value = label.innerText.substr(0, MAX_NAME_LEN); - input.style.display = 'inline'; - input.select(); - }); -} - -function bind_title_events() { - let title_label = document.querySelector('.title-label'); - let title_input = document.getElementById('title-input'); - let title = document.querySelector('.title'); - - enable_edit_on_click(title, title_input, title_label); -} - -function create_label_input(row, row_idx, row_name) { - let input = document.createElement('input'); - input.id = `input-tier-${unique_id++}`; - input.type = 'text'; - input.addEventListener('change', resize_headers); - let label = document.createElement('label'); - label.htmlFor = input.id; - label.innerText = row_name; - - let header = row.querySelector('.header'); - all_headers.splice(row_idx, 0, [header, input, label]); - header.appendChild(label); - header.appendChild(input); - - enable_edit_on_click(header, input, label); -} - -function resize_headers() { - let max_width = headers_orig_min_width; - for (let [other_header, _i, label] of all_headers) { - max_width = Math.max(max_width, label.clientWidth); - } - - for (let [other_header, _i2, _l2] of all_headers) { - other_header.style.minWidth = `${max_width}px`; - } -} - -function add_row(index, name) { - let div = document.createElement('div'); - let header = document.createElement('span'); - let items = document.createElement('span'); - div.classList.add('row'); - header.classList.add('header'); - items.classList.add('items'); - div.appendChild(header); - div.appendChild(items); - let row_buttons = document.createElement('div'); - row_buttons.classList.add('row-buttons'); - let btn_plus_up = document.createElement('input'); - btn_plus_up.type = "button"; - btn_plus_up.value = '+'; - btn_plus_up.title = "Add row above"; - btn_plus_up.addEventListener('click', (evt) => { - let parent_div = evt.target.parentNode.parentNode; - let rows = Array.from(tierlist_div.children); - let idx = rows.indexOf(parent_div); - console.assert(idx >= 0); - add_row(idx, ''); - recompute_header_colors(); - }); - let btn_rm = document.createElement('input'); - btn_rm.type = "button"; - btn_rm.value = '-'; - btn_rm.title = "Remove row"; - btn_rm.addEventListener('click', (evt) => { - let rows = Array.from(tierlist_div.querySelectorAll('.row')); - if (rows.length < 2) return; - let parent_div = evt.target.parentNode.parentNode; - let idx = rows.indexOf(parent_div); - console.assert(idx >= 0); - if (rows[idx].querySelectorAll('img').length === 0 || - confirm(`Remove tier ${rows[idx].querySelector('.header label').innerText}? (This will move back all its content to the untiered pool)`)) { - rm_row(idx); - } - recompute_header_colors(); - }); - let btn_plus_down = document.createElement('input'); - btn_plus_down.type = "button"; - btn_plus_down.value = '+'; - btn_plus_down.title = "Add row below"; - btn_plus_down.addEventListener('click', (evt) => { - let parent_div = evt.target.parentNode.parentNode; - let rows = Array.from(tierlist_div.children); - let idx = rows.indexOf(parent_div); - console.assert(idx >= 0); - add_row(idx + 1, name); - recompute_header_colors(); - }); - row_buttons.appendChild(btn_plus_up); - row_buttons.appendChild(btn_rm); - row_buttons.appendChild(btn_plus_down); - div.appendChild(row_buttons); - - let rows = tierlist_div.children; - if (index === rows.length) { - tierlist_div.appendChild(div); - } else { - let nxt_child = rows[index]; - tierlist_div.insertBefore(div, nxt_child); - } - - make_accept_drop(div); - create_label_input(div, index, name); - - return div; -} - -function rm_row(idx) { - let row = tierlist_div.children[idx]; - reset_row(row); - tierlist_div.removeChild(row); -} - -function recompute_header_colors() { - tierlist_div.querySelectorAll('.row').forEach((row, row_idx) => { - let color = TIER_COLORS[row_idx % TIER_COLORS.length]; - row.querySelector('.header').style.backgroundColor = color; - }); -} - -function bind_trash_events() { - let trash = document.getElementById('trash'); - trash.classList.add('droppable'); - trash.addEventListener('dragenter', (evt) => { - evt.preventDefault(); - evt.target.src = '/static/img/trash-2.svg'; - }); - trash.addEventListener('dragexit', (evt) => { - evt.preventDefault(); - evt.target.src = '/static/img/trash.svg'; - }); - trash.addEventListener('dragover', (evt) => { - evt.preventDefault(); - }); - trash.addEventListener('drop', (evt) => { - evt.preventDefault(); - evt.target.src = '/static/img/trash.svg'; - if (dragged_image) { - let dragged_image_parent = dragged_image.parentNode; - if (dragged_image_parent.tagName.toUpperCase() === 'SPAN' && - dragged_image_parent.classList.contains('item')) { - let containing_tr = dragged_image_parent.parentNode; - containing_tr.removeChild(dragged_image_parent); - } - dragged_image.remove(); - } - }); -} - -function bind_toggle_layout_events() { - let toggle = document.getElementById('toggle-layout'); - toggle.addEventListener('click', () => { - set_layout((cur_layout + 1) % 2); - }); -} - -function set_layout(layout) { - let main = document.getElementsByClassName("main-content")[0]; - if (layout === LAYOUT_VERTICAL) { - main.classList.add("vertical"); - } else { - main.classList.remove("vertical"); - } - cur_layout = layout; -} - -function is_url(str) { - try { - new URL(str); - return true; - } catch (e) { - return false; - } -} - -async function try_load_tierlist_json() { - const load_from_url = new URLSearchParams(window.location.search).get('url'); - if (load_from_url !== null && is_url(load_from_url)) { - try { - let result = await fetch(load_from_url); - result = await result.json(); - hard_reset_list(); - load_tierlist(result); - } catch (e) { console.error(e); } - } -} diff --git a/static/styles.css b/static/styles.css deleted file mode 100644 index 994c882..0000000 --- a/static/styles.css +++ /dev/null @@ -1,329 +0,0 @@ -body { - background-color: #333; - font-family: sans-serif; -} - -.title { - color: #ddd; - font-size: 38px; - user-select: none; - text-align: center; - margin-bottom: 20px; - min-height: 38px; - cursor: pointer; -} - -.title label { - cursor: pointer; -} - -.title input { - display: none; - background: transparent; - border: 0px; - color: #ddd; - font-size: 38px; -} - -.title input:focus { - background: #666; -} - -.main-content { - display: flex; - flex-flow: column; -} - -.main-content.vertical { - flex-flow: row !important; -} - -.vertical .tierlist { - width: 80%; -} - -.toggleable-container { - display: flex; - flex-flow: column; - flex-grow: 1; -} - -.tierlist span { - min-width: 100px; - min-height: 100px; - display: flex; - align-items: center; - flex-flow: row; - font-size: 30px; - font-family: sans-serif; - border: 0; - padding: 0; -} - -.tierlist div.row { - border: 0px solid #666; - border-top-width: 1px; - border-right-width: 1px; - display: flex; - user-select: none; -} - -.tierlist div:last-child { - border-bottom-width: 1px !important; -} - -.tierlist div.row:hover { - background-color: #666; -} - -.tierlist div.row.drag-entered { - background-color: #888; -} - -span.header { - justify-content: center; - align-self: stretch; - cursor: pointer; -} - -span.header label { - cursor: pointer; -} - -span.header input[type=text] { - display: none; - height: 50px; - font-size: 30px; - text-align: center; -} - -span.items { - display: flex; - flex-wrap: wrap; - flex-grow: 1; - justify-content: left; - pointer-events: none; - height: fit-content; -} - -span.item { - pointer-events: auto; -} - -.images { - display: flex; - border: 1px solid #666; - height: 200px; - overflow-y: auto; - flex-wrap: wrap; - flex-grow: 1; - width: 100%; - align-content: flex-start; -} - -.images.drag-entered { - background-color: #888; -} - -img.draggable { - cursor: grab; - max-height: 100px; - width: auto; - height: auto; - object-fit: contain; -} - -img.draggable:hover, .button:hover { - filter: brightness(0.6); -} - -img.draggable.dragged, .button:active { - filter: brightness(0.4); -} - -.button img { - user-select: none; - width: 100px; -} - -.bottom-container { - display: flex; - flex-flow: row; - align-items: center; - margin-top: 15px; - flex-grow: 1; -} - -.vertical .bottom-container { - flex-flow: column !important; - margin-left: 15px; - margin-top: 0px !important; -} - -.bottom-container input { - border: 0; - padding: 0; - display: none; -} - -.bottom-container > div { - margin: 0; -} - -.button { - border: 1px solid #666; - height: 100px; -} - -.row-buttons { - display: flex; - flex-direction: column; - align-items: stretch; - justify-content: space-evenly; - opacity: 0.2; - transition: 200ms linear; -} - -.row-buttons:hover { - opacity: 1; - transition: 200ms linear; -} - -.buttons-container { - display: flex; - flex-wrap: wrap; - width: 270px; -} - -.vertical .buttons-container { - justify-content: center; -} - -.gh-link { - position: absolute; - top: 5px; - color: #ccc; - text-decoration: none; -} - -.top-container { - position: absolute; - top: 5px; - right: 5px; - height: 60px; - display: flex; - flex-flow: row; -} - -.top-container * { - height: 100%; - overflow: hidden; - margin: 0; - padding-left: 5px; - padding-right: 5px; - border: 0; -} - -.top-container input { - border: 0; - padding: 0; - display: none; -} - -#trash { - opacity: 0.4; -} - -#trash:hover { - opacity: 1; -} - -.hint { - font-style: italic; - font-size: small; - color: #ccc; - padding: 0px 10px; -} - -.modal { - position: fixed; - z-index: 1000; - left: 0; - top: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.6); - display: none; - align-items: center; - justify-content: center; -} - - -.modal-content { - background-color: #444; - padding: 30px; - border-radius: 10px; - box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.7); - width: 90%; - max-width: 800px; - max-height: 90vh; - text-align: center; - color: #ddd; - display: flex; - flex-direction: column; - align-items: center; - overflow-y: auto; -} - -#modal-img { - max-width: 100%; - max-height: 40vh; - object-fit: contain; - border-radius: 5px; - margin-bottom: 10px; -} - -#modal-title { - width: 80%; - padding: 8px 15px; - margin: 10px auto; - border: 1px solid #666; - border-radius: 5px; - font-size: 16px; - background-color: #333; - color: #ddd; - text-align: center; -} - -#modal-description { - width: 80%; - height: 25vh; - padding: 12px 15px; - margin: 10px auto; - border: 1px solid #666; - border-radius: 5px; - font-size: 14px; - background-color: #333; - color: #ddd; - resize: vertical; -} - -#modal-title:focus { - outline: none; - border-color: #4a4a4a; - background-color: #3a3a3a; -} - -#modal-save { - background: #2c662f; - color: #ddd; - border: none; - padding: 12px 25px; - cursor: pointer; - margin-top: 15px; - border-radius: 5px; - font-size: 16px; - transition: background-color 0.2s ease; - align-self: center; - min-width: 120px; -} \ No newline at end of file diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..994c882 --- /dev/null +++ b/styles.css @@ -0,0 +1,329 @@ +body { + background-color: #333; + font-family: sans-serif; +} + +.title { + color: #ddd; + font-size: 38px; + user-select: none; + text-align: center; + margin-bottom: 20px; + min-height: 38px; + cursor: pointer; +} + +.title label { + cursor: pointer; +} + +.title input { + display: none; + background: transparent; + border: 0px; + color: #ddd; + font-size: 38px; +} + +.title input:focus { + background: #666; +} + +.main-content { + display: flex; + flex-flow: column; +} + +.main-content.vertical { + flex-flow: row !important; +} + +.vertical .tierlist { + width: 80%; +} + +.toggleable-container { + display: flex; + flex-flow: column; + flex-grow: 1; +} + +.tierlist span { + min-width: 100px; + min-height: 100px; + display: flex; + align-items: center; + flex-flow: row; + font-size: 30px; + font-family: sans-serif; + border: 0; + padding: 0; +} + +.tierlist div.row { + border: 0px solid #666; + border-top-width: 1px; + border-right-width: 1px; + display: flex; + user-select: none; +} + +.tierlist div:last-child { + border-bottom-width: 1px !important; +} + +.tierlist div.row:hover { + background-color: #666; +} + +.tierlist div.row.drag-entered { + background-color: #888; +} + +span.header { + justify-content: center; + align-self: stretch; + cursor: pointer; +} + +span.header label { + cursor: pointer; +} + +span.header input[type=text] { + display: none; + height: 50px; + font-size: 30px; + text-align: center; +} + +span.items { + display: flex; + flex-wrap: wrap; + flex-grow: 1; + justify-content: left; + pointer-events: none; + height: fit-content; +} + +span.item { + pointer-events: auto; +} + +.images { + display: flex; + border: 1px solid #666; + height: 200px; + overflow-y: auto; + flex-wrap: wrap; + flex-grow: 1; + width: 100%; + align-content: flex-start; +} + +.images.drag-entered { + background-color: #888; +} + +img.draggable { + cursor: grab; + max-height: 100px; + width: auto; + height: auto; + object-fit: contain; +} + +img.draggable:hover, .button:hover { + filter: brightness(0.6); +} + +img.draggable.dragged, .button:active { + filter: brightness(0.4); +} + +.button img { + user-select: none; + width: 100px; +} + +.bottom-container { + display: flex; + flex-flow: row; + align-items: center; + margin-top: 15px; + flex-grow: 1; +} + +.vertical .bottom-container { + flex-flow: column !important; + margin-left: 15px; + margin-top: 0px !important; +} + +.bottom-container input { + border: 0; + padding: 0; + display: none; +} + +.bottom-container > div { + margin: 0; +} + +.button { + border: 1px solid #666; + height: 100px; +} + +.row-buttons { + display: flex; + flex-direction: column; + align-items: stretch; + justify-content: space-evenly; + opacity: 0.2; + transition: 200ms linear; +} + +.row-buttons:hover { + opacity: 1; + transition: 200ms linear; +} + +.buttons-container { + display: flex; + flex-wrap: wrap; + width: 270px; +} + +.vertical .buttons-container { + justify-content: center; +} + +.gh-link { + position: absolute; + top: 5px; + color: #ccc; + text-decoration: none; +} + +.top-container { + position: absolute; + top: 5px; + right: 5px; + height: 60px; + display: flex; + flex-flow: row; +} + +.top-container * { + height: 100%; + overflow: hidden; + margin: 0; + padding-left: 5px; + padding-right: 5px; + border: 0; +} + +.top-container input { + border: 0; + padding: 0; + display: none; +} + +#trash { + opacity: 0.4; +} + +#trash:hover { + opacity: 1; +} + +.hint { + font-style: italic; + font-size: small; + color: #ccc; + padding: 0px 10px; +} + +.modal { + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.6); + display: none; + align-items: center; + justify-content: center; +} + + +.modal-content { + background-color: #444; + padding: 30px; + border-radius: 10px; + box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.7); + width: 90%; + max-width: 800px; + max-height: 90vh; + text-align: center; + color: #ddd; + display: flex; + flex-direction: column; + align-items: center; + overflow-y: auto; +} + +#modal-img { + max-width: 100%; + max-height: 40vh; + object-fit: contain; + border-radius: 5px; + margin-bottom: 10px; +} + +#modal-title { + width: 80%; + padding: 8px 15px; + margin: 10px auto; + border: 1px solid #666; + border-radius: 5px; + font-size: 16px; + background-color: #333; + color: #ddd; + text-align: center; +} + +#modal-description { + width: 80%; + height: 25vh; + padding: 12px 15px; + margin: 10px auto; + border: 1px solid #666; + border-radius: 5px; + font-size: 14px; + background-color: #333; + color: #ddd; + resize: vertical; +} + +#modal-title:focus { + outline: none; + border-color: #4a4a4a; + background-color: #3a3a3a; +} + +#modal-save { + background: #2c662f; + color: #ddd; + border: none; + padding: 12px 25px; + cursor: pointer; + margin-top: 15px; + border-radius: 5px; + font-size: 16px; + transition: background-color 0.2s ease; + align-self: center; + min-width: 120px; +} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html deleted file mode 100644 index 0e5cc84..0000000 --- a/templates/index.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - Offline TierMaker - - - - -
- - -
- GitHub -
-
-
-
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
-

Hint: you can paste an image into this page to have it show up in the image list.

-
-
-
- -
- - -
-
- - - \ No newline at end of file diff --git a/tiers.css b/tiers.css new file mode 100644 index 0000000..1036155 --- /dev/null +++ b/tiers.css @@ -0,0 +1,195 @@ +body { + background-color: #333; + font-family: sans-serif; + margin: 0; + padding: 0; +} + +.title { + color: #fff; + font-size: 24px; + user-select: none; + text-align: center; + margin-bottom: 20px; +} + +.title label { + cursor: default; + +} + +.main-content { + display: flex; + flex-flow: column; +} + +.main-content.vertical { + flex-flow: row !important; +} + +.vertical .tierlist { + width: 80%; +} + +.tierlist span { + min-width: 100px; + min-height: 100px; + display: flex; + align-items: center; + justify-content: center; + flex-flow: row; + font-size: 30px; + font-family: sans-serif; + border: 0; + padding: 0; + box-sizing: border-box; +} + +.tierlist div.row { + border: 1px solid #666; + display: flex; + user-select: none; + height: 100px; + align-items: stretch; + margin: 0; +} + +span.header { + justify-content: center; + color: black; + width: 100px; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +span.items { + display: flex; + flex-wrap: wrap; + justify-content: left; + flex-grow: 1; + height: 100%; +} + +.tierlist div.row:last-child { + border-bottom-width: 1px !important; +} + +.tierlist div.row:hover { + background-color: #666; +} + +img { + cursor: pointer; + max-height: 100px; + width: auto; + height: auto; + object-fit: contain; +} + +.bottom-container { + display: flex; + align-items: center; + justify-content: center; + margin-top: 15px; +} + +.buttons-container { + display: flex; + width: fit-content; + justify-content: center; + gap: 20px; +} + + +.button { + border: 1px solid #666; + background-color: #444; + height: 100px; + width: 100px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: filter 0.2s ease; +} + +.button img { + user-select: none; + width: 60px; +} + +.button:hover { + filter: brightness(0.8); +} + +/* GitHub Link */ +.gh-link { + position: absolute; + top: 5px; + color: #ccc; + text-decoration: none; +} + +/* Modal (View–Only) */ +.modal { + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.6); + display: none; + align-items: center; + justify-content: center; +} + +.modal-content { + background-color: #444; + padding: 30px; + border-radius: 10px; + box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.7); + width: 90%; + max-width: 800px; + max-height: 90vh; + text-align: center; + color: #ddd; + display: flex; + flex-direction: column; + align-items: center; + overflow-y: auto; +} + +#modal-img { + max-width: 100%; + max-height: 40vh; + object-fit: contain; + border-radius: 5px; + margin-bottom: 10px; +} + +#modal-title, #modal-description { + width: 80%; + padding: 8px 15px; + margin: 10px auto; + border: 1px solid #666; + border-radius: 5px; + font-size: 16px; + background-color: #333; + color: #ddd; + text-align: center; + cursor: default; /* Read-only */ +} + +#modal-description { + height: 25vh; + resize: none; /* Read-only textarea */ +} + +/* Removed Elements */ +.row-buttons, .top-container, .images { + display: none !important; +} diff --git a/tiers.html b/tiers.html new file mode 100644 index 0000000..0c7880b --- /dev/null +++ b/tiers.html @@ -0,0 +1,32 @@ + + + + + Exported Tier List + + + + +
+

My TierList

+
+ GitHub +
+
+
+
+
+
+
+
+
+ + + diff --git a/tiers.js b/tiers.js new file mode 100644 index 0000000..a80a71a --- /dev/null +++ b/tiers.js @@ -0,0 +1,137 @@ +'use strict'; + +const MAX_NAME_LEN = 200; +const DEFAULT_TIERS = ['S', 'A', 'B', 'C', 'D', 'E', 'F']; +const TIER_COLORS = [ + '#ff6666', + '#f0a731', + '#f4d95b', + '#66ff66', + '#58c8f4', + '#5b76f4', + '#f45bed' +]; + +let unique_id = 0; +let tierlist_div; + +window.addEventListener('load', () => { + tierlist_div = document.querySelector('.tierlist'); + + for (let i = 0; i < DEFAULT_TIERS.length; ++i) { + add_row(i, DEFAULT_TIERS[i]); + } + recompute_header_colors(); + + const modal = document.getElementById('image-modal'); + const modalImg = document.getElementById('modal-img'); + const modalTitle = document.getElementById('modal-title'); + const modalDesc = document.getElementById('modal-description'); + const modalClose = document.querySelector('.modal .close'); + let currentModalImage = null; + + function showModal(img) { + currentModalImage = img; + document.body.style.overflow = 'hidden'; + modal.style.display = 'flex'; + modalImg.src = img.src; + modalTitle.value = img.dataset.title || 'No title'; + modalDesc.value = img.dataset.description || 'No description'; + } + + modalClose.addEventListener('click', () => { + modal.style.display = 'none'; + document.body.style.overflow = 'auto'; + }); + + window.addEventListener('click', (evt) => { + if (evt.target == modal) { + modal.style.display = 'none'; + document.body.style.overflow = 'auto'; + } + }); + + tierlist_div.addEventListener('click', (evt) => { + if (evt.target.tagName.toUpperCase() === 'IMG') { + showModal(evt.target); + } + }); + + hard_reset_list(); + load_tierlist(EMBEDDED_JSON); +}); + + +function create_img_with_src(src) { + let img = document.createElement('img'); + img.src = src; + img.style.userSelect = 'none'; + + img.addEventListener("mouseenter", (evt) => { + const title = evt.target.dataset.title; + if (title) { + evt.target.title = title; + } + }); + + return img; +} + +function hard_reset_list() { + tierlist_div.innerHTML = ''; +} + +function load_tierlist(serialized_tierlist) { + document.querySelector('.title-label').innerText = serialized_tierlist.title; + for (let idx in serialized_tierlist.rows) { + let ser_row = serialized_tierlist.rows[idx]; + let elem = add_row(idx, ser_row.name); + + for (let img_obj of (ser_row.imgs || [])) { + let img = create_img_with_src(img_obj.src); + img.dataset.title = img_obj.title || ''; + img.dataset.description = img_obj.description || ''; + let td = document.createElement('span'); + td.classList.add('item'); + td.appendChild(img); + let items_container = elem.querySelector('.items'); + items_container.appendChild(td); + } + + elem.querySelector('.header').innerText = ser_row.name; + } + recompute_header_colors(); +} + +function add_row(index, name) { + let div = document.createElement('div'); + div.classList.add('row'); + + let header = document.createElement('span'); + header.classList.add('header'); + header.innerText = name; + + let items = document.createElement('span'); + items.classList.add('items'); + + div.appendChild(header); + div.appendChild(items); + + let rows = tierlist_div.children; + if (index >= rows.length) { + tierlist_div.appendChild(div); + } else { + let nxt_child = rows[index]; + tierlist_div.insertBefore(div, nxt_child); + } + + return div; +} + +function recompute_header_colors() { + let rows = tierlist_div.querySelectorAll('.row'); + rows.forEach((row, row_idx) => { + let color = TIER_COLORS[row_idx % TIER_COLORS.length]; + row.querySelector('.header').style.backgroundColor = color; + }); +} -- cgit v1.2.3