zenno: format

This commit is contained in:
2026-03-31 12:07:38 -04:00
parent 08deedea8f
commit 22ca5c98f3
15 changed files with 196 additions and 179 deletions

View File

@@ -7,22 +7,22 @@
<svelte:head><link rel="icon" href={favicon} /></svelte:head>
<nav class="flex min-w-full p-4 mb-4 shadow-md">
<span class="hidden md:inline flex-1">
<nav class="mb-4 flex min-w-full p-4 shadow-md">
<span class="hidden flex-1 md:inline">
<a href="/" class="text-7xl">Zenno Rob Roy</a>
</span>
<span class="flex-1 text-center">
<a href="/" class="md:hidden block mx-8 my-1 font-semibold">Zenno Rob Roy</a>
<a href="/inherit" class="inline-block mx-8 my-1">Inheritance Chance</a>
<a href="/spark" class="inline-block mx-8 my-1">Spark Chance</a>
<a href="/vet" class="inline-block mx-8 my-1">My Veterans</a>
<a href="/convo" class="inline-block mx-8 my-1">Lobby Conversations</a>
<a href="/" class="mx-8 my-1 block font-semibold md:hidden">Zenno Rob Roy</a>
<a href="/inherit" class="mx-8 my-1 inline-block">Inheritance Chance</a>
<a href="/spark" class="mx-8 my-1 inline-block">Spark Chance</a>
<a href="/vet" class="mx-8 my-1 inline-block">My Veterans</a>
<a href="/convo" class="mx-8 my-1 inline-block">Lobby Conversations</a>
</span>
</nav>
<div class="md:min-w-7xl md:max-w-7xl md:m-auto">
<div class="md:m-auto md:max-w-7xl md:min-w-7xl">
{@render children()}
</div>
<footer class="p-4 mt-32 inset-x-0 bottom-0 border-t text-center text-[14px]">
Umamusume: Pretty Derby tools by <a href="https://zephyrtronium.date/">zephyrtronium</a>.<br>
<footer class="inset-x-0 bottom-0 mt-32 border-t p-4 text-center text-[14px]">
Umamusume: Pretty Derby tools by <a href="https://zephyrtronium.date/">zephyrtronium</a>.<br />
All data is generated from the game's local database.
</footer>

View File

@@ -1,11 +1,21 @@
<script lang="ts">
import CharaPick from "$lib/CharaPick.svelte";
import CharaPick from '$lib/CharaPick.svelte';
let selChara = $state(0);
let selChara = $state(0);
</script>
<h1>Welcome to SvelteKit</h1>
<CharaPick id="test-chara" bind:value={selChara} />
<p>selected character is id {selChara}</p>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
<p>Lorem ipsum (/ ˌ l ɔː. r ə m ˈ ɪ p. s ə m/ LOR-əm IP-səm) is a dummy or placeholder text commonly used in graphic design, publishing, and web development. It is typically a corrupted version of De finibus bonorum et malorum, a 1st-century BC text by the Roman statesman and philosopher Cicero, with words altered, added, and removed to make it nonsensical and improper Latin. The first two words are the truncation of dolorem ipsum ("pain itself"). Lorem ipsum's purpose is to permit a page layout to be designed, independently of the copy that will subsequently populate it, or to demonstrate various fonts of a typeface without meaningful text that could be distracting. Versions of the Lorem ipsum text have been used in typesetting since the 1960s, when advertisements for Letraset transfer sheets popularized it. Lorem ipsum was introduced to the digital world in the mid-1980s, when Aldus employed it in graphic and word-processing templates for its desktop publishing program PageMaker. Other popular word processors, including Pages and Microsoft Word, have since adopted Lorem ipsum, as have many LaTeX packages, web content</p>
<p>
Lorem ipsum (/ ˌ l ɔː. r ə m ˈ ɪ p. s ə m/ LOR-əm IP-səm) is a dummy or placeholder text commonly used in graphic design,
publishing, and web development. It is typically a corrupted version of De finibus bonorum et malorum, a 1st-century BC text by
the Roman statesman and philosopher Cicero, with words altered, added, and removed to make it nonsensical and improper Latin.
The first two words are the truncation of dolorem ipsum ("pain itself"). Lorem ipsum's purpose is to permit a page layout to be
designed, independently of the copy that will subsequently populate it, or to demonstrate various fonts of a typeface without
meaningful text that could be distracting. Versions of the Lorem ipsum text have been used in typesetting since the 1960s, when
advertisements for Letraset transfer sheets popularized it. Lorem ipsum was introduced to the digital world in the mid-1980s,
when Aldus employed it in graphic and word-processing templates for its desktop publishing program PageMaker. Other popular word
processors, including Pages and Microsoft Word, have since adopted Lorem ipsum, as have many LaTeX packages, web content
</p>

View File

@@ -1,69 +1,69 @@
<script lang="ts">
import { charaNames } from "$lib/data/character";
import { byChara, locations, groupPopulars } from "$lib/data/convo";
import CharaPick from "$lib/CharaPick.svelte";
import { charaNames } from '$lib/data/character';
import { byChara, locations, groupPopulars } from '$lib/data/convo';
import CharaPick from '$lib/CharaPick.svelte';
let charaID = $state(1001)
let convo = $state(1)
let charaID = $state(1001);
let convo = $state(1);
let options = $derived(byChara.global.get(charaID) ?? [])
let cur = $derived(options.find((c) => c.number === convo))
let options = $derived(byChara.global.get(charaID) ?? []);
let cur = $derived(options.find((c) => c.number === convo));
function suggest(n: number, pops: typeof groupPopulars['global']) {
if (cur == null) {
return []
}
const u = pops[locations[cur.location].group]
.filter((s) => charaNames.get(s[0]) != null && s[0] !== cur.chara_1 && s[0] !== cur.chara_2 && s[0] !== cur.chara_3)
if (u.length <= n) {
return u
}
return u.filter((s) => s[1] >= u[n][1])
}
function suggest(n: number, pops: (typeof groupPopulars)['global']) {
if (cur == null) {
return [];
}
const u = pops[locations[cur.location].group].filter(
(s) => charaNames.get(s[0]) != null && s[0] !== cur.chara_1 && s[0] !== cur.chara_2 && s[0] !== cur.chara_3,
);
if (u.length <= n) {
return u;
}
return u.filter((s) => s[1] >= u[n][1]);
}
</script>
<h1>Lobby Conversations</h1>
<div class="flex text-center mt-8">
<div class="flex-1">
<CharaPick id="chara" label="Character" bind:value={charaID} required />
</div>
<div class="flex-1">
<label for="convo">Conversation</label>
<select id="convo" bind:value={convo} class="w-full">
{#each options as opt}
<option value={opt.number}>Slice of Life {opt.number}</option>
{/each}
</select>
</div>
<div class="mt-8 flex text-center">
<div class="flex-1">
<CharaPick id="chara" label="Character" bind:value={charaID} required />
</div>
<div class="flex-1">
<label for="convo">Conversation</label>
<select id="convo" bind:value={convo} class="w-full">
{#each options as opt}
<option value={opt.number}>Slice of Life {opt.number}</option>
{/each}
</select>
</div>
</div>
{#if cur}
<div class="transition-shadow shadow-sm hover:shadow-md">
<div class="flex mt-8 text-center">
<span class="flex-1">{charaNames.get(cur.chara_1)?.en ?? 'someone not a trainee'}</span>
{#if cur.chara_2}
<span class="flex-1">{charaNames.get(cur.chara_2)?.en ?? 'someone not a trainee'}</span>
{/if}
{#if cur.chara_3}
<span class="flex-1">{charaNames.get(cur.chara_3)?.en ?? 'someone not a trainee'}</span>
{/if}
</div>
<div class="flex mt-4 w-full text-center">
<span class="flex-1">at {locations[cur.location].name.en}</span>
</div>
</div>
<div class="block mt-4 text-center">
<span>Characters who appear here most often:</span>
</div>
<div class="grid md:grid-cols-4 mt-4 text-center transition-shadow ease-in hover:ease-out shadow-sm hover:shadow-md">
{#each suggest(8, groupPopulars.global) as s}
<span>{charaNames.get(s[0])?.en}: {s[1]}&#xd7;</span>
{/each}
</div>
<div class="block mt-4 text-center">
<span>
Set characters that appear more often to fixed positions
(main, upgrades, story, races)
to maximize the chance of getting this conversation.
</span>
</div>
{/if}
<div class="shadow-sm transition-shadow hover:shadow-md">
<div class="mt-8 flex text-center">
<span class="flex-1">{charaNames.get(cur.chara_1)?.en ?? 'someone not a trainee'}</span>
{#if cur.chara_2}
<span class="flex-1">{charaNames.get(cur.chara_2)?.en ?? 'someone not a trainee'}</span>
{/if}
{#if cur.chara_3}
<span class="flex-1">{charaNames.get(cur.chara_3)?.en ?? 'someone not a trainee'}</span>
{/if}
</div>
<div class="mt-4 flex w-full text-center">
<span class="flex-1">at {locations[cur.location].name.en}</span>
</div>
</div>
<div class="mt-4 block text-center">
<span>Characters who appear here most often:</span>
</div>
<div class="mt-4 grid text-center shadow-sm transition-shadow ease-in hover:shadow-md hover:ease-out md:grid-cols-4">
{#each suggest(8, groupPopulars.global) as s}
<span>{charaNames.get(s[0])?.en}: {s[1]}&#xd7;</span>
{/each}
</div>
<div class="mt-4 block text-center">
<span>
Set characters that appear more often to fixed positions (main, upgrades, story, races) to maximize the chance of getting
this conversation.
</span>
</div>
{/if}

View File

@@ -2,5 +2,5 @@
@import './sakura-vars.css';
@theme {
--text-sm: 1.25rem;
--text-sm: 1.25rem;
}

View File

@@ -13,7 +13,7 @@
--text: #292222;
}
[data-theme="iron goddess"] {
[data-theme='iron goddess'] {
--blossom: #424b51;
--fade: #64707a;
--bg: #fff2e2;
@@ -21,7 +21,7 @@
--text: #2c2923;
}
[data-theme="main sequence"] {
[data-theme='main sequence'] {
--blossom: #3a5425;
--fade: #698650;
--bg: #fffde5;
@@ -29,7 +29,7 @@
--text: #5e592a;
}
[data-theme="sorcery"] {
[data-theme='sorcery'] {
--blossom: #5a5a69;
--fade: #868698;
--bg: #e5f4e5;
@@ -37,7 +37,7 @@
--text: #323932;
}
[data-theme="cirrus"] {
[data-theme='cirrus'] {
--blossom: #565a4b;
--fade: #9da587;
--bg: #e5f6fa;
@@ -45,7 +45,7 @@
--text: #31393b;
}
[data-theme="oxygen"] {
[data-theme='oxygen'] {
--blossom: #162011;
--fade: #343932;
--bg: #e1e2e4;
@@ -53,7 +53,7 @@
--text: #27282c;
}
[data-theme="dauphin"] {
[data-theme='dauphin'] {
--blossom: #171e1c;
--fade: #485b58;
--bg: #ebe5f8;
@@ -61,7 +61,7 @@
--text: #1c1a20;
}
[data-theme="diamond-burned"] {
[data-theme='diamond-burned'] {
--blossom: #0f0d0b;
--fade: #4d4743;
--bg: #f8ebf2;
@@ -69,7 +69,7 @@
--text: #3e363a;
}
[data-theme="chi"] {
[data-theme='chi'] {
--blossom: #908975;
--fade: #fff8e5;
--bg: #110c0c;
@@ -77,7 +77,7 @@
--text: #cfa9a9;
}
[data-theme="darjeeling"] {
[data-theme='darjeeling'] {
--blossom: #ba949c;
--fade: #f8e1e6;
--bg: #1c160d;
@@ -85,7 +85,7 @@
--text: #c9b9a0;
}
[data-theme="subgiant"] {
[data-theme='subgiant'] {
--blossom: #9fad8a;
--fade: #e8f2d7;
--bg: #16130b;
@@ -93,7 +93,7 @@
--text: #bbb396;
}
[data-theme="goblin"] {
[data-theme='goblin'] {
--blossom: #7a808e;
--fade: #dae1ef;
--bg: #070905;
@@ -101,7 +101,7 @@
--text: #acbd9f;
}
[data-theme="altostratus"] {
[data-theme='altostratus'] {
--blossom: #a8a0b7;
--fade: #e5dbf7;
--bg: #0c0f0f;
@@ -109,7 +109,7 @@
--text: #8da4a4;
}
[data-theme="silicon"] {
[data-theme='silicon'] {
--blossom: #717f63;
--fade: #c4d4b3;
--bg: #050a0f;
@@ -117,7 +117,7 @@
--text: #838e9a;
}
[data-theme="imperator"] {
[data-theme='imperator'] {
--blossom: #93a0a3;
--fade: #f3fbfd;
--bg: #0e0c12;
@@ -125,7 +125,7 @@
--text: #a8a1b1;
}
[data-theme="mædi"] {
[data-theme='mædi'] {
--blossom: #ccd3b6;
--fade: #fdfbf3;
--bg: #10090f;
@@ -136,7 +136,7 @@
/* Body */
html {
font-size: 62.5%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
}
body {
@@ -168,7 +168,7 @@ h4,
h5,
h6 {
line-height: 1.1;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
font-weight: 700;
margin-top: 3rem;
margin-bottom: 1.5rem;
@@ -281,7 +281,7 @@ samp {
white-space: pre-wrap;
}
pre>code {
pre > code {
padding: 0;
background-color: transparent;
white-space: pre;
@@ -319,10 +319,10 @@ textarea {
.button,
button,
input[type=submit],
input[type=reset],
input[type=button],
input[type=file]::file-selector-button {
input[type='submit'],
input[type='reset'],
input[type='button'],
input[type='file']::file-selector-button {
display: inline-block;
padding: 5px 10px;
text-align: center;
@@ -338,20 +338,20 @@ input[type=file]::file-selector-button {
.button[disabled],
button[disabled],
input[type=submit][disabled],
input[type=reset][disabled],
input[type=button][disabled],
input[type=file]::file-selector-button[disabled] {
input[type='submit'][disabled],
input[type='reset'][disabled],
input[type='button'][disabled],
input[type='file']::file-selector-button[disabled] {
cursor: default;
opacity: 0.5;
}
.button:hover,
button:hover,
input[type=submit]:hover,
input[type=reset]:hover,
input[type=button]:hover,
input[type=file]::file-selector-button:hover {
input[type='submit']:hover,
input[type='reset']:hover,
input[type='button']:hover,
input[type='file']::file-selector-button:hover {
background-color: var(--fade);
color: var(--bg);
outline: 0;
@@ -359,10 +359,10 @@ input[type=file]::file-selector-button:hover {
.button:focus-visible,
button:focus-visible,
input[type=submit]:focus-visible,
input[type=reset]:focus-visible,
input[type=button]:focus-visible,
input[type=file]::file-selector-button:focus-visible {
input[type='submit']:focus-visible,
input[type='reset']:focus-visible,
input[type='button']:focus-visible,
input[type='file']::file-selector-button:focus-visible {
outline-style: solid;
outline-width: 2px;
}
@@ -388,7 +388,7 @@ input:focus {
outline: 0;
}
input[type=checkbox]:focus {
input[type='checkbox']:focus {
outline: 1px dotted var(--blossom);
}
@@ -398,4 +398,4 @@ fieldset {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
}
}

View File

@@ -1,3 +1,6 @@
<h1>Spark Generation Chance</h1>
<p>Given a legacy, calculate the chance of generating each spark if you fulfill the conditions to do so, and the distribution of total spark counts.</p>
<p>
Given a legacy, calculate the chance of generating each spark if you fulfill the conditions to do so, and the distribution of
total spark counts.
</p>
<p>TODO</p>