|
3 | 3 | <head> |
4 | 4 | <meta charset="UTF-8" /> |
5 | 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
6 | | - <title>Map Hasher</title> |
7 | | - <meta name="description" content="Minecraft map tools — convert .dat and .cache files to PNG, extract map hashes" /> |
8 | | - <link rel="icon" href="/favicon.svg" type="image/svg+xml" /> |
| 6 | + <title>EvMod Tools</title> |
| 7 | + <meta name="description" content="Minecraft map tools — convert .dat/.cache/.nbt/.litematic/.schem files and extract map hashes" /> |
| 8 | + <link rel="icon" href="%BASE_URL%favicon.png" type="image/png" /> |
9 | 9 |
|
10 | | - <meta property="og:title" content="Map Hash Extractor" /> |
11 | | - <meta property="og:description" content="Extract map hashes from binary files and PNG images" /> |
| 10 | + <meta property="og:title" content="EvMod Tools" /> |
| 11 | + <meta property="og:description" content="Convert map-related files and extract map hashes" /> |
12 | 12 | <meta property="og:type" content="website" /> |
13 | 13 | <!-- GitHub Pages SPA redirect restore --> |
14 | 14 | <script type="text/javascript"> |
15 | 15 | (function(l) { |
| 16 | + var configuredBase = "%BASE_URL%"; |
| 17 | + var base = configuredBase.endsWith("/") ? configuredBase : configuredBase + "/"; |
| 18 | + var baseNoSlash = base === "/" ? "/" : base.slice(0, -1); |
| 19 | + var hasAppBase = base === "/" || l.pathname === baseNoSlash || l.pathname.startsWith(base); |
| 20 | + var needsTrailingSlash = function(pathname) { |
| 21 | + var q = pathname.indexOf("?"); |
| 22 | + var pathOnly = q < 0 ? pathname : pathname.slice(0, q); |
| 23 | + if (pathOnly.endsWith("/")) return false; |
| 24 | + var last = pathOnly.split("/").pop() || ""; |
| 25 | + return last.indexOf(".") < 0; |
| 26 | + }; |
| 27 | + var withSlash = function(pathname) { |
| 28 | + var q = pathname.indexOf("?"); |
| 29 | + if (q < 0) return pathname.endsWith("/") ? pathname : pathname + "/"; |
| 30 | + var pathOnly = pathname.slice(0, q); |
| 31 | + var query = pathname.slice(q); |
| 32 | + return (pathOnly.endsWith("/") ? pathOnly : pathOnly + "/") + query; |
| 33 | + }; |
| 34 | + |
| 35 | + if (configuredBase !== "/" && l.pathname === baseNoSlash) { |
| 36 | + l.replace(base + l.search + l.hash); |
| 37 | + return; |
| 38 | + } |
| 39 | + |
16 | 40 | if (l.search[1] === '/') { |
17 | 41 | var decoded = l.search.slice(1).split('&').map(function(s) { |
18 | 42 | return s.replace(/~and~/g, '&') |
19 | 43 | }).join('?'); |
| 44 | + var basePath = l.pathname.endsWith("/") ? l.pathname.slice(0, -1) : l.pathname; |
| 45 | + var restored = basePath + decoded; |
| 46 | + if (hasAppBase && needsTrailingSlash(restored)) restored = withSlash(restored); |
20 | 47 | window.history.replaceState(null, null, |
21 | | - l.pathname.slice(0, -1) + decoded + l.hash |
| 48 | + restored + l.hash |
22 | 49 | ); |
| 50 | + return; |
| 51 | + } |
| 52 | + |
| 53 | + if (hasAppBase && needsTrailingSlash(l.pathname)) { |
| 54 | + l.replace(withSlash(l.pathname) + l.search + l.hash); |
23 | 55 | } |
24 | 56 | }(window.location)) |
25 | 57 | </script> |
|
0 commit comments